{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.7.9 64-bit ('ML': conda)",
   "metadata": {
    "interpreter": {
     "hash": "539eeca01c4a82e9e0248c7d96d3e95516d644c0bbc096dd3e480eeded1964cf"
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "source": [
    "<center><h1>第三章 索引</h1></center>"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "source": [
    "## 一、索引器\n",
    "### 1. 表的列索引\n",
    "列索引是最常见的索引形式，一般通过`[]`来实现。通过`[列名]`可以从`DataFrame`中取出相应的列，返回值为`Series`，例如从表中取出姓名一列："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "0      Gaopeng Yang\n",
       "1    Changqiang You\n",
       "2           Mei Sun\n",
       "3      Xiaojuan Sun\n",
       "4       Gaojuan You\n",
       "Name: Name, dtype: object"
      ]
     },
     "metadata": {},
     "execution_count": 2
    }
   ],
   "source": [
    "df = pd.read_csv('../data/learn_pandas.csv', usecols = ['School', 'Grade', 'Name', 'Gender', 'Weight', 'Transfer'])\n",
    "df['Name'].head()"
   ]
  },
  {
   "source": [
    "如果要取出多个列，则可以通过`[列名组成的列表]`，其返回值为一个`DataFrame`，例如从表中取出性别和姓名两列："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   Gender            Name\n",
       "0  Female    Gaopeng Yang\n",
       "1    Male  Changqiang You\n",
       "2    Male         Mei Sun\n",
       "3  Female    Xiaojuan Sun\n",
       "4    Male     Gaojuan You"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>Gender</th>\n      <th>Name</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>Female</td>\n      <td>Gaopeng Yang</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>Male</td>\n      <td>Changqiang You</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>Male</td>\n      <td>Mei Sun</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>Female</td>\n      <td>Xiaojuan Sun</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>Male</td>\n      <td>Gaojuan You</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 3
    }
   ],
   "source": [
    "df[['Gender', 'Name']].head()"
   ]
  },
  {
   "source": [
    "此外，若要取出单列，且列名中不包含空格，则可以用`.列名`取出，这和`[列名]`是等价的："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "0      Gaopeng Yang\n",
       "1    Changqiang You\n",
       "2           Mei Sun\n",
       "3      Xiaojuan Sun\n",
       "4       Gaojuan You\n",
       "Name: Name, dtype: object"
      ]
     },
     "metadata": {},
     "execution_count": 4
    }
   ],
   "source": [
    "df.Name.head()"
   ]
  },
  {
   "source": [
    "### 2. 序列的行索引\n",
    "\n",
    "【a】以字符串为索引的`Series`\n",
    "\n",
    "如果取出单个索引的对应元素，则可以使用`[item]`，若`Series`只有单个值对应，则返回这个标量值，如果有多个值对应，则返回一个`Series`："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "a    1\n",
       "a    3\n",
       "a    4\n",
       "a    5\n",
       "dtype: int64"
      ]
     },
     "metadata": {},
     "execution_count": 5
    }
   ],
   "source": [
    "s = pd.Series([1, 2, 3, 4, 5, 6], index=['a', 'b', 'a', 'a', 'a', 'c'])\n",
    "s['a']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "metadata": {},
     "execution_count": 6
    }
   ],
   "source": [
    "s['b']"
   ]
  },
  {
   "source": [
    "如果取出多个索引的对应元素，则可以使用`[items的列表]`："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "c    6\n",
       "b    2\n",
       "dtype: int64"
      ]
     },
     "metadata": {},
     "execution_count": 7
    }
   ],
   "source": [
    "s[['c', 'b']]"
   ]
  },
  {
   "source": [
    "如果想要取出某两个索引之间的元素，并且这两个索引是在整个索引中唯一出现，则可以使用切片,，同时需要注意这里的切片会包含两个端点："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "c    6\n",
       "a    4\n",
       "b    2\n",
       "dtype: int64"
      ]
     },
     "metadata": {},
     "execution_count": 8
    }
   ],
   "source": [
    "s['c': 'b': -2]"
   ]
  },
  {
   "source": [
    "如果前后端点的值重复出现，那么需要经过排序才能使用切片："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "KeyError(\"Cannot get left slice bound for non-unique label: 'a'\")"
      ]
     },
     "metadata": {},
     "execution_count": 9
    }
   ],
   "source": [
    "try:\n",
    "    s['a': 'b']\n",
    "except Exception as e:\n",
    "    Err_Msg = e\n",
    "Err_Msg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "a    1\n",
       "a    3\n",
       "a    4\n",
       "a    5\n",
       "b    2\n",
       "dtype: int64"
      ]
     },
     "metadata": {},
     "execution_count": 10
    }
   ],
   "source": [
    "s.sort_index()['a': 'b']"
   ]
  },
  {
   "source": [
    "【b】以整数为索引的`Series`\n",
    "\n",
    "在使用数据的读入函数时，如果不特别指定所对应的列作为索引，那么会生成从0开始的整数索引作为默认索引。当然，任意一组符合长度要求的整数都可以作为索引。\n",
    "\n",
    "和字符串一样，如果使用`[int]`或`[int_list]`，则可以取出对应索引**元素**的值："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "1    a\n",
       "1    c\n",
       "dtype: object"
      ]
     },
     "metadata": {},
     "execution_count": 11
    }
   ],
   "source": [
    "s = pd.Series(['a', 'b', 'c', 'd', 'e', 'f'], index=[1, 3, 1, 2, 5, 4])\n",
    "s[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "2    d\n",
       "3    b\n",
       "dtype: object"
      ]
     },
     "metadata": {},
     "execution_count": 12
    }
   ],
   "source": [
    "s[[2,3]]"
   ]
  },
  {
   "source": [
    "如果使用整数切片，则会取出对应索引**位置**的值，注意这里的整数切片同`Python`中的切片一样不包含右端点："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "3    b\n",
       "2    d\n",
       "dtype: object"
      ]
     },
     "metadata": {},
     "execution_count": 13
    }
   ],
   "source": [
    "s[1:-1:2]"
   ]
  },
  {
   "source": [
    "#### 【WARNING】关于索引类型的说明\n",
    "\n",
    "如果不想陷入麻烦，那么请不要把纯浮点以及任何混合类型（字符串、整数、浮点类型等的混合）作为索引，否则可能会在具体的操作时报错或者返回非预期的结果，并且在实际的数据分析中也不存在这样做的动机。\n",
    "\n",
    "#### 【END】\n",
    "\n",
    "### 3. loc索引器\n",
    "\n",
    "前面讲到了对`DataFrame`的列进行选取，下面要讨论其行的选取。对于表而言，有两种索引器，一种是基于**元素**的`loc`索引器，另一种是基于**位置**的`iloc`索引器。\n",
    "\n",
    "`loc`索引器的一般形式是`loc[*, *]`，其中第一个`*`代表行的选择，第二个`*`代表列的选择，如果省略第二个位置写作`loc[*]`，这个`*`是指行的筛选。其中，`*`的位置一共有五类合法对象，分别是：单个元素、元素列表、元素切片、布尔列表以及函数，下面将依次说明。\n",
    "\n",
    "为了演示相应操作，先利用`set_index`方法把`Name`列设为索引，关于该函数的其他用法将在多级索引一章介绍。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                       School      Grade  Gender  Weight  \\\n",
       "Name                                                                       \n",
       "Gaopeng Yang    Shanghai Jiao Tong University   Freshman  Female    46.0   \n",
       "Changqiang You              Peking University   Freshman    Male    70.0   \n",
       "Mei Sun         Shanghai Jiao Tong University     Senior    Male    89.0   \n",
       "Xiaojuan Sun                 Fudan University  Sophomore  Female    41.0   \n",
       "Gaojuan You                  Fudan University  Sophomore    Male    74.0   \n",
       "\n",
       "               Transfer  \n",
       "Name                     \n",
       "Gaopeng Yang          N  \n",
       "Changqiang You        N  \n",
       "Mei Sun               N  \n",
       "Xiaojuan Sun          N  \n",
       "Gaojuan You           N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Gaopeng Yang</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Freshman</td>\n      <td>Female</td>\n      <td>46.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Changqiang You</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Male</td>\n      <td>70.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Mei Sun</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Xiaojuan Sun</th>\n      <td>Fudan University</td>\n      <td>Sophomore</td>\n      <td>Female</td>\n      <td>41.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Gaojuan You</th>\n      <td>Fudan University</td>\n      <td>Sophomore</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 14
    }
   ],
   "source": [
    "df_demo = df.set_index('Name')\n",
    "df_demo.head()"
   ]
  },
  {
   "source": [
    "【a】`*`为单个元素\n",
    "\n",
    "此时，直接取出相应的行或列，如果该元素在索引中重复则结果为`DataFrame`，否则为`Series`："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                  School      Grade  Gender  Weight Transfer\n",
       "Name                                                                        \n",
       "Qiang Sun            Tsinghua University     Junior  Female    53.0        N\n",
       "Qiang Sun            Tsinghua University  Sophomore  Female    40.0        N\n",
       "Qiang Sun  Shanghai Jiao Tong University     Junior  Female     NaN        N"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Qiang Sun</th>\n      <td>Tsinghua University</td>\n      <td>Junior</td>\n      <td>Female</td>\n      <td>53.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Qiang Sun</th>\n      <td>Tsinghua University</td>\n      <td>Sophomore</td>\n      <td>Female</td>\n      <td>40.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Qiang Sun</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Junior</td>\n      <td>Female</td>\n      <td>NaN</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 15
    }
   ],
   "source": [
    "df_demo.loc['Qiang Sun'] # 多个人叫此名字"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "School      Shanghai Jiao Tong University\n",
       "Grade                              Junior\n",
       "Gender                             Female\n",
       "Weight                               53.0\n",
       "Transfer                                N\n",
       "Name: Quan Zhao, dtype: object"
      ]
     },
     "metadata": {},
     "execution_count": 16
    }
   ],
   "source": [
    "df_demo.loc['Quan Zhao'] # 名字唯一"
   ]
  },
  {
   "source": [
    "也可以同时选择行和列："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Name\n",
       "Qiang Sun              Tsinghua University\n",
       "Qiang Sun              Tsinghua University\n",
       "Qiang Sun    Shanghai Jiao Tong University\n",
       "Name: School, dtype: object"
      ]
     },
     "metadata": {},
     "execution_count": 17
    }
   ],
   "source": [
    "df_demo.loc['Qiang Sun', 'School'] # 返回Series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "'Shanghai Jiao Tong University'"
      ]
     },
     "metadata": {},
     "execution_count": 18
    }
   ],
   "source": [
    "df_demo.loc['Quan Zhao', 'School'] # 返回单个元素"
   ]
  },
  {
   "source": [
    "【b】`*`为元素列表\n",
    "\n",
    "此时，取出列表中所有元素值对应的行或列："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                  School  Gender\n",
       "Name                                            \n",
       "Qiang Sun            Tsinghua University  Female\n",
       "Qiang Sun            Tsinghua University  Female\n",
       "Qiang Sun  Shanghai Jiao Tong University  Female\n",
       "Quan Zhao  Shanghai Jiao Tong University  Female"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Gender</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Qiang Sun</th>\n      <td>Tsinghua University</td>\n      <td>Female</td>\n    </tr>\n    <tr>\n      <th>Qiang Sun</th>\n      <td>Tsinghua University</td>\n      <td>Female</td>\n    </tr>\n    <tr>\n      <th>Qiang Sun</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Female</td>\n    </tr>\n    <tr>\n      <th>Quan Zhao</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Female</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 19
    }
   ],
   "source": [
    "df_demo.loc[['Qiang Sun','Quan Zhao'], ['School','Gender']]"
   ]
  },
  {
   "source": [
    "【c】`*`为切片\n",
    "\n",
    "之前的`Series`使用字符串索引时提到，如果是唯一值的起点和终点字符，那么就可以使用切片，并且包含两个端点，如果不唯一则报错："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                      School      Grade  Gender\n",
       "Name                                                           \n",
       "Gaojuan You                 Fudan University  Sophomore    Male\n",
       "Xiaoli Qian              Tsinghua University   Freshman  Female\n",
       "Qiang Chu      Shanghai Jiao Tong University   Freshman  Female\n",
       "Gaoqiang Qian            Tsinghua University     Junior  Female"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Gaojuan You</th>\n      <td>Fudan University</td>\n      <td>Sophomore</td>\n      <td>Male</td>\n    </tr>\n    <tr>\n      <th>Xiaoli Qian</th>\n      <td>Tsinghua University</td>\n      <td>Freshman</td>\n      <td>Female</td>\n    </tr>\n    <tr>\n      <th>Qiang Chu</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Freshman</td>\n      <td>Female</td>\n    </tr>\n    <tr>\n      <th>Gaoqiang Qian</th>\n      <td>Tsinghua University</td>\n      <td>Junior</td>\n      <td>Female</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 20
    }
   ],
   "source": [
    "df_demo.loc['Gaojuan You':'Gaoqiang Qian', 'School':'Gender']"
   ]
  },
  {
   "source": [
    "需要注意的是，如果`DataFrame`使用整数索引，其使用整数切片的时候和上面字符串索引的要求一致，都是**元素**切片，包含端点且起点、终点不允许有重复值。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                          School   Grade  Gender  Weight Transfer\n",
       "5               Fudan University  Junior  Female    46.0        N\n",
       "4            Tsinghua University  Senior  Female    50.0        N\n",
       "3  Shanghai Jiao Tong University  Senior  Female    45.0        N"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>5</th>\n      <td>Fudan University</td>\n      <td>Junior</td>\n      <td>Female</td>\n      <td>46.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>Tsinghua University</td>\n      <td>Senior</td>\n      <td>Female</td>\n      <td>50.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Female</td>\n      <td>45.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 21
    }
   ],
   "source": [
    "df_loc_slice_demo = df_demo.copy()\n",
    "df_loc_slice_demo.index = range(df_demo.shape[0],0,-1)\n",
    "df_loc_slice_demo.loc[5:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Empty DataFrame\n",
       "Columns: [School, Grade, Gender, Weight, Transfer]\n",
       "Index: []"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n  </thead>\n  <tbody>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 22
    }
   ],
   "source": [
    "df_loc_slice_demo.loc[3:5] # 没有返回，说明不是整数位置切片"
   ]
  },
  {
   "source": [
    "【d】`*`为布尔列表\n",
    "\n",
    "在实际的数据处理中，根据条件来筛选行是极其常见的，此处传入`loc`的布尔列表与`DataFrame`长度相同，且列表为`True`的位置所对应的行会被选中，`False`则会被剔除。\n",
    "\n",
    "例如，选出体重超过70kg的学生："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                      School      Grade Gender  Weight  \\\n",
       "Name                                                                     \n",
       "Mei Sun        Shanghai Jiao Tong University     Senior   Male    89.0   \n",
       "Gaojuan You                 Fudan University  Sophomore   Male    74.0   \n",
       "Xiaopeng Zhou  Shanghai Jiao Tong University   Freshman   Male    74.0   \n",
       "Xiaofeng Sun             Tsinghua University     Senior   Male    71.0   \n",
       "Qiang Zheng    Shanghai Jiao Tong University     Senior   Male    87.0   \n",
       "\n",
       "              Transfer  \n",
       "Name                    \n",
       "Mei Sun              N  \n",
       "Gaojuan You          N  \n",
       "Xiaopeng Zhou        N  \n",
       "Xiaofeng Sun         N  \n",
       "Qiang Zheng          N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Mei Sun</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Gaojuan You</th>\n      <td>Fudan University</td>\n      <td>Sophomore</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Xiaopeng Zhou</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Freshman</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Xiaofeng Sun</th>\n      <td>Tsinghua University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>71.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Qiang Zheng</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>87.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 23
    }
   ],
   "source": [
    "df_demo.loc[df_demo.Weight>70].head()"
   ]
  },
  {
   "source": [
    "前面所提到的传入元素列表，也可以通过`isin`方法返回的布尔列表等价写出，例如选出所有大一和大四的同学信息："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                       School     Grade  Gender  Weight  \\\n",
       "Name                                                                      \n",
       "Gaopeng Yang    Shanghai Jiao Tong University  Freshman  Female    46.0   \n",
       "Changqiang You              Peking University  Freshman    Male    70.0   \n",
       "Mei Sun         Shanghai Jiao Tong University    Senior    Male    89.0   \n",
       "Xiaoli Qian               Tsinghua University  Freshman  Female    51.0   \n",
       "Qiang Chu       Shanghai Jiao Tong University  Freshman  Female    52.0   \n",
       "\n",
       "               Transfer  \n",
       "Name                     \n",
       "Gaopeng Yang          N  \n",
       "Changqiang You        N  \n",
       "Mei Sun               N  \n",
       "Xiaoli Qian           N  \n",
       "Qiang Chu             N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Gaopeng Yang</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Freshman</td>\n      <td>Female</td>\n      <td>46.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Changqiang You</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Male</td>\n      <td>70.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Mei Sun</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Xiaoli Qian</th>\n      <td>Tsinghua University</td>\n      <td>Freshman</td>\n      <td>Female</td>\n      <td>51.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Qiang Chu</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Freshman</td>\n      <td>Female</td>\n      <td>52.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 24
    }
   ],
   "source": [
    "df_demo.loc[df_demo.Grade.isin(['Freshman', 'Senior'])].head()"
   ]
  },
  {
   "source": [
    "对于复合条件而言，可以用`|（或）, &（且）, ~（取反）`的组合来实现，例如选出复旦大学中体重超过70kg的大四学生，或者北大男生中体重超过80kg的非大四的学生："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                           School     Grade Gender  Weight Transfer\n",
       "Name                                                               \n",
       "Qiang Han       Peking University  Freshman   Male    87.0        N\n",
       "Chengpeng Zhou   Fudan University    Senior   Male    81.0        N\n",
       "Changpeng Zhao  Peking University  Freshman   Male    83.0        N\n",
       "Chengpeng Qian   Fudan University    Senior   Male    73.0        Y"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Qiang Han</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Male</td>\n      <td>87.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Chengpeng Zhou</th>\n      <td>Fudan University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>81.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Changpeng Zhao</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Male</td>\n      <td>83.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Chengpeng Qian</th>\n      <td>Fudan University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>73.0</td>\n      <td>Y</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 25
    }
   ],
   "source": [
    "condition_1_1 = df_demo.School == 'Fudan University'\n",
    "condition_1_2 = df_demo.Grade == 'Senior'\n",
    "condition_1_3 = df_demo.Weight > 70\n",
    "condition_1 = condition_1_1 & condition_1_2 & condition_1_3\n",
    "condition_2_1 = df_demo.School == 'Peking University'\n",
    "condition_2_2 = df_demo.Grade == 'Senior'\n",
    "condition_2_3 = df_demo.Weight > 80\n",
    "condition_2 = condition_2_1 & (~condition_2_2) & condition_2_3\n",
    "df_demo.loc[condition_1 | condition_2]"
   ]
  },
  {
   "source": [
    "#### 【练一练】\n",
    "\n",
    "`select_dtypes`是一个实用函数，它能够从表中选出相应类型的列，若要选出所有数值型的列，只需使用`.select_dtypes('number')`，请利用布尔列表选择的方法结合`DataFrame`的`dtypes`属性在`learn_pandas`数据集上实现这个功能。\n",
    "\n",
    "#### 【END】\n",
    "\n",
    "【e】`*`为函数\n",
    "\n",
    "这里的函数，必须以前面的四种合法形式之一为返回值，并且函数的输入值为`DataFrame`本身。假设仍然是上述复合条件筛选的例子，可以把逻辑写入一个函数中再返回，需要注意的是函数的形式参数`x`本质上即为`df_demo`："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                           School     Grade Gender  Weight Transfer\n",
       "Name                                                               \n",
       "Qiang Han       Peking University  Freshman   Male    87.0        N\n",
       "Chengpeng Zhou   Fudan University    Senior   Male    81.0        N\n",
       "Changpeng Zhao  Peking University  Freshman   Male    83.0        N\n",
       "Chengpeng Qian   Fudan University    Senior   Male    73.0        Y"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Qiang Han</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Male</td>\n      <td>87.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Chengpeng Zhou</th>\n      <td>Fudan University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>81.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Changpeng Zhao</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Male</td>\n      <td>83.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Chengpeng Qian</th>\n      <td>Fudan University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>73.0</td>\n      <td>Y</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 26
    }
   ],
   "source": [
    "def condition(x):\n",
    "    condition_1_1 = x.School == 'Fudan University'\n",
    "    condition_1_2 = x.Grade == 'Senior'\n",
    "    condition_1_3 = x.Weight > 70\n",
    "    condition_1 = condition_1_1 & condition_1_2 & condition_1_3\n",
    "    condition_2_1 = x.School == 'Peking University'\n",
    "    condition_2_2 = x.Grade == 'Senior'\n",
    "    condition_2_3 = x.Weight > 80\n",
    "    condition_2 = condition_2_1 & (~condition_2_2) & condition_2_3\n",
    "    result = condition_1 | condition_2\n",
    "    return result\n",
    "df_demo.loc[condition]"
   ]
  },
  {
   "source": [
    "此外，还支持使用`lambda`表达式，其返回值也同样必须是先前提到的四种形式之一："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "'Female'"
      ]
     },
     "metadata": {},
     "execution_count": 27
    }
   ],
   "source": [
    "df_demo.loc[lambda x:'Quan Zhao', lambda x:'Gender']"
   ]
  },
  {
   "source": [
    "由于函数无法返回如`start: end: step`的切片形式，故返回切片时要用`slice`对象进行包装："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                      School      Grade  Gender  Weight  \\\n",
       "Name                                                                      \n",
       "Gaojuan You                 Fudan University  Sophomore    Male    74.0   \n",
       "Xiaoli Qian              Tsinghua University   Freshman  Female    51.0   \n",
       "Qiang Chu      Shanghai Jiao Tong University   Freshman  Female    52.0   \n",
       "Gaoqiang Qian            Tsinghua University     Junior  Female    50.0   \n",
       "\n",
       "              Transfer  \n",
       "Name                    \n",
       "Gaojuan You          N  \n",
       "Xiaoli Qian          N  \n",
       "Qiang Chu            N  \n",
       "Gaoqiang Qian        N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Gaojuan You</th>\n      <td>Fudan University</td>\n      <td>Sophomore</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Xiaoli Qian</th>\n      <td>Tsinghua University</td>\n      <td>Freshman</td>\n      <td>Female</td>\n      <td>51.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Qiang Chu</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Freshman</td>\n      <td>Female</td>\n      <td>52.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Gaoqiang Qian</th>\n      <td>Tsinghua University</td>\n      <td>Junior</td>\n      <td>Female</td>\n      <td>50.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 28
    }
   ],
   "source": [
    "df_demo.loc[lambda x: slice('Gaojuan You', 'Gaoqiang Qian')]"
   ]
  },
  {
   "source": [
    "最后需要指出的是，对于`Series`也可以使用`loc`索引，其遵循的原则与`DataFrame`中用于行筛选的`loc[*]`完全一致，此处不再赘述。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "#### 【WARNING】不要使用链式赋值\n",
    "\n",
    "在对表或者序列赋值时，应当在使用一层索引器后直接进行赋值操作，这样做是由于进行多次索引后赋值是赋在临时返回的`copy`副本上的，而没有真正修改元素从而报出`SettingWithCopyWarning`警告。例如，下面给出的例子："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "\nA value is trying to be set on a copy of a slice from a DataFrame.\nTry using .loc[row_indexer,col_indexer] = value instead\n\nSee the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n"
     ]
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   A  B\n",
       "0  0  0\n",
       "1  1  0\n",
       "2 -1  0"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>A</th>\n      <th>B</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>0</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>1</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>-1</td>\n      <td>0</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 29
    }
   ],
   "source": [
    "df_chain = pd.DataFrame([[0,0],[1,0],[-1,0]], columns=list('AB'))\n",
    "df_chain\n",
    "import warnings\n",
    "with warnings.catch_warnings():\n",
    "    warnings.filterwarnings('error')\n",
    "    try:\n",
    "        df_chain[df_chain.A!=0].B = 1 # 使用方括号列索引后，再使用点的列索引\n",
    "    except Warning as w:\n",
    "        Warning_Msg = w\n",
    "print(Warning_Msg)\n",
    "df_chain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   A  B\n",
       "0  0  0\n",
       "1  1  1\n",
       "2 -1  1"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>A</th>\n      <th>B</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>0</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>1</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>-1</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 30
    }
   ],
   "source": [
    "df_chain.loc[df_chain.A!=0,'B'] = 1\n",
    "df_chain"
   ]
  },
  {
   "source": [
    "#### 【END】\n",
    "\n",
    "### 4. iloc索引器\n",
    "\n",
    "`iloc`的使用与`loc`完全类似，只不过是针对位置进行筛选，在相应的`*`位置处一共也有五类合法对象，分别是：整数、整数列表、整数切片、布尔列表以及函数，函数的返回值必须是前面的四类合法对象中的一个，其输入同样也为`DataFrame`本身。\n"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "'Freshman'"
      ]
     },
     "metadata": {},
     "execution_count": 31
    }
   ],
   "source": [
    "df_demo.iloc[1, 1] # 第二行第二列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                       School     Grade\n",
       "Name                                                   \n",
       "Gaopeng Yang    Shanghai Jiao Tong University  Freshman\n",
       "Changqiang You              Peking University  Freshman"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Gaopeng Yang</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Freshman</td>\n    </tr>\n    <tr>\n      <th>Changqiang You</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 32
    }
   ],
   "source": [
    "df_demo.iloc[[0, 1], [0, 1]] # 前两行前两列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                Gender  Weight\n",
       "Name                          \n",
       "Changqiang You    Male    70.0\n",
       "Mei Sun           Male    89.0\n",
       "Xiaojuan Sun    Female    41.0"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>Gender</th>\n      <th>Weight</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Changqiang You</th>\n      <td>Male</td>\n      <td>70.0</td>\n    </tr>\n    <tr>\n      <th>Mei Sun</th>\n      <td>Male</td>\n      <td>89.0</td>\n    </tr>\n    <tr>\n      <th>Xiaojuan Sun</th>\n      <td>Female</td>\n      <td>41.0</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 33
    }
   ],
   "source": [
    "df_demo.iloc[1: 4, 2:4] # 切片不包含结束端点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                       School      Grade  Gender  Weight  \\\n",
       "Name                                                                       \n",
       "Changqiang You              Peking University   Freshman    Male    70.0   \n",
       "Mei Sun         Shanghai Jiao Tong University     Senior    Male    89.0   \n",
       "Xiaojuan Sun                 Fudan University  Sophomore  Female    41.0   \n",
       "\n",
       "               Transfer  \n",
       "Name                     \n",
       "Changqiang You        N  \n",
       "Mei Sun               N  \n",
       "Xiaojuan Sun          N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Changqiang You</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Male</td>\n      <td>70.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Mei Sun</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Xiaojuan Sun</th>\n      <td>Fudan University</td>\n      <td>Sophomore</td>\n      <td>Female</td>\n      <td>41.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 34
    }
   ],
   "source": [
    "df_demo.iloc[lambda x: slice(1, 4)] # 传入切片为返回值的函数"
   ]
  },
  {
   "source": [
    "在使用布尔列表的时候要特别注意，不能传入`Series`而必须传入序列的`values`，否则会报错。因此，在使用布尔筛选的时候还是应当优先考虑`loc`的方式。\n",
    "\n",
    "例如，选出体重超过80kg的学生："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                       School      Grade Gender  Weight  \\\n",
       "Name                                                                      \n",
       "Mei Sun         Shanghai Jiao Tong University     Senior   Male    89.0   \n",
       "Qiang Zheng     Shanghai Jiao Tong University     Senior   Male    87.0   \n",
       "Qiang Han                   Peking University   Freshman   Male    87.0   \n",
       "Chengpeng Zhou               Fudan University     Senior   Male    81.0   \n",
       "Feng Han        Shanghai Jiao Tong University  Sophomore   Male    82.0   \n",
       "\n",
       "               Transfer  \n",
       "Name                     \n",
       "Mei Sun               N  \n",
       "Qiang Zheng           N  \n",
       "Qiang Han             N  \n",
       "Chengpeng Zhou        N  \n",
       "Feng Han              N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>Name</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Mei Sun</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Qiang Zheng</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>87.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Qiang Han</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Male</td>\n      <td>87.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Chengpeng Zhou</th>\n      <td>Fudan University</td>\n      <td>Senior</td>\n      <td>Male</td>\n      <td>81.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Feng Han</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Sophomore</td>\n      <td>Male</td>\n      <td>82.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 35
    }
   ],
   "source": [
    "df_demo.iloc[(df_demo.Weight>80).values].head()"
   ]
  },
  {
   "source": [
    "对`Series`而言同样也可以通过`iloc`返回相应位置的值或子序列："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "'Peking University'"
      ]
     },
     "metadata": {},
     "execution_count": 36
    }
   ],
   "source": [
    "df_demo.School.iloc[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Name\n",
       "Changqiang You    Peking University\n",
       "Xiaojuan Sun       Fudan University\n",
       "Name: School, dtype: object"
      ]
     },
     "metadata": {},
     "execution_count": 37
    }
   ],
   "source": [
    "df_demo.School.iloc[1:5:2]"
   ]
  },
  {
   "source": [
    "### 5. query方法\n",
    "\n",
    "在`pandas`中，支持把字符串形式的查询表达式传入`query`方法来查询数据，其表达式的执行结果必须返回布尔列表。在进行复杂索引时，由于这种检索方式无需像普通方法一样重复使用`DataFrame`的名字来引用列名，一般而言会使代码长度在不降低可读性的前提下有所减少。\n",
    "\n",
    "例如，将`loc`一节中的复合条件查询例子可以如下改写："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                School     Grade            Name Gender  Weight Transfer\n",
       "38   Peking University  Freshman       Qiang Han   Male    87.0        N\n",
       "66    Fudan University    Senior  Chengpeng Zhou   Male    81.0        N\n",
       "99   Peking University  Freshman  Changpeng Zhao   Male    83.0        N\n",
       "131   Fudan University    Senior  Chengpeng Qian   Male    73.0        Y"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>38</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Qiang Han</td>\n      <td>Male</td>\n      <td>87.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>66</th>\n      <td>Fudan University</td>\n      <td>Senior</td>\n      <td>Chengpeng Zhou</td>\n      <td>Male</td>\n      <td>81.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>99</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Changpeng Zhao</td>\n      <td>Male</td>\n      <td>83.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>131</th>\n      <td>Fudan University</td>\n      <td>Senior</td>\n      <td>Chengpeng Qian</td>\n      <td>Male</td>\n      <td>73.0</td>\n      <td>Y</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 38
    }
   ],
   "source": [
    "df.query('((School == \"Fudan University\")&'\n",
    "         ' (Grade == \"Senior\")&'\n",
    "         ' (Weight > 70))|'\n",
    "         '((School == \"Peking University\")&'\n",
    "         ' (Grade != \"Senior\")&'\n",
    "         ' (Weight > 80))')"
   ]
  },
  {
   "source": [
    "在`query`表达式中，帮用户注册了所有来自`DataFrame`的列名，所有属于该`Series`的方法都可以被调用，和正常的函数调用并没有区别，例如查询体重超过均值的学生："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                           School      Grade            Name  Gender  Weight  \\\n",
       "1               Peking University   Freshman  Changqiang You    Male    70.0   \n",
       "2   Shanghai Jiao Tong University     Senior         Mei Sun    Male    89.0   \n",
       "4                Fudan University  Sophomore     Gaojuan You    Male    74.0   \n",
       "10  Shanghai Jiao Tong University   Freshman   Xiaopeng Zhou    Male    74.0   \n",
       "14            Tsinghua University     Senior    Xiaomei Zhou  Female    57.0   \n",
       "\n",
       "   Transfer  \n",
       "1         N  \n",
       "2         N  \n",
       "4         N  \n",
       "10        N  \n",
       "14        N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>1</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Changqiang You</td>\n      <td>Male</td>\n      <td>70.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Mei Sun</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>Fudan University</td>\n      <td>Sophomore</td>\n      <td>Gaojuan You</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>10</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Freshman</td>\n      <td>Xiaopeng Zhou</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>14</th>\n      <td>Tsinghua University</td>\n      <td>Senior</td>\n      <td>Xiaomei Zhou</td>\n      <td>Female</td>\n      <td>57.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 39
    }
   ],
   "source": [
    "df.query('Weight > Weight.mean()').head()"
   ]
  },
  {
   "source": [
    "#### 【NOTE】query中引用带空格的列名\n",
    "\n",
    "对于含有空格的列名，需要使用`` `col name` ``的方式进行引用。\n",
    "\n",
    "#### 【END】\n",
    "\n",
    "同时，在`query`中还注册了若干英语的字面用法，帮助提高可读性，例如：`or, and, or, is in, not in`。例如，筛选出男生中不是大一大二的学生："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                           School   Grade           Name Gender  Weight  \\\n",
       "2   Shanghai Jiao Tong University  Senior        Mei Sun   Male    89.0   \n",
       "16            Tsinghua University  Junior  Xiaoqiang Qin   Male    68.0   \n",
       "17            Tsinghua University  Junior      Peng Wang   Male    65.0   \n",
       "18            Tsinghua University  Senior   Xiaofeng Sun   Male    71.0   \n",
       "21  Shanghai Jiao Tong University  Senior  Xiaopeng Shen   Male    62.0   \n",
       "\n",
       "   Transfer  \n",
       "2         N  \n",
       "16        N  \n",
       "17        N  \n",
       "18        N  \n",
       "21      NaN  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Mei Sun</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>16</th>\n      <td>Tsinghua University</td>\n      <td>Junior</td>\n      <td>Xiaoqiang Qin</td>\n      <td>Male</td>\n      <td>68.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>17</th>\n      <td>Tsinghua University</td>\n      <td>Junior</td>\n      <td>Peng Wang</td>\n      <td>Male</td>\n      <td>65.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>18</th>\n      <td>Tsinghua University</td>\n      <td>Senior</td>\n      <td>Xiaofeng Sun</td>\n      <td>Male</td>\n      <td>71.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>21</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Xiaopeng Shen</td>\n      <td>Male</td>\n      <td>62.0</td>\n      <td>NaN</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 40
    }
   ],
   "source": [
    "df.query('(Grade not in [\"Freshman\", \"Sophomore\"]) and (Gender == \"Male\")').head()"
   ]
  },
  {
   "source": [
    "此外，在字符串中出现与列表的比较时，`==`和`!=`分别表示元素出现在列表和没有出现在列表，等价于`is in`和`not in`，例如查询所有大三和大四的学生："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                           School   Grade           Name  Gender  Weight  \\\n",
       "2   Shanghai Jiao Tong University  Senior        Mei Sun    Male    89.0   \n",
       "7             Tsinghua University  Junior  Gaoqiang Qian  Female    50.0   \n",
       "9               Peking University  Junior        Juan Xu  Female     NaN   \n",
       "11            Tsinghua University  Junior    Xiaoquan Lv  Female    43.0   \n",
       "12  Shanghai Jiao Tong University  Senior       Peng You  Female    48.0   \n",
       "\n",
       "   Transfer  \n",
       "2         N  \n",
       "7         N  \n",
       "9         N  \n",
       "11        N  \n",
       "12      NaN  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Mei Sun</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>7</th>\n      <td>Tsinghua University</td>\n      <td>Junior</td>\n      <td>Gaoqiang Qian</td>\n      <td>Female</td>\n      <td>50.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>9</th>\n      <td>Peking University</td>\n      <td>Junior</td>\n      <td>Juan Xu</td>\n      <td>Female</td>\n      <td>NaN</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>11</th>\n      <td>Tsinghua University</td>\n      <td>Junior</td>\n      <td>Xiaoquan Lv</td>\n      <td>Female</td>\n      <td>43.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>12</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Senior</td>\n      <td>Peng You</td>\n      <td>Female</td>\n      <td>48.0</td>\n      <td>NaN</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 41
    }
   ],
   "source": [
    "df.query('Grade == [\"Junior\", \"Senior\"]').head()"
   ]
  },
  {
   "source": [
    "对于`query`中的字符串，如果要引用外部变量，只需在变量名前加`@`符号。例如，取出体重位于70kg到80kg之间的学生："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                           School      Grade            Name Gender  Weight  \\\n",
       "1               Peking University   Freshman  Changqiang You   Male    70.0   \n",
       "4                Fudan University  Sophomore     Gaojuan You   Male    74.0   \n",
       "10  Shanghai Jiao Tong University   Freshman   Xiaopeng Zhou   Male    74.0   \n",
       "18            Tsinghua University     Senior    Xiaofeng Sun   Male    71.0   \n",
       "35              Peking University   Freshman      Gaoli Zhao   Male    78.0   \n",
       "\n",
       "   Transfer  \n",
       "1         N  \n",
       "4         N  \n",
       "10        N  \n",
       "18        N  \n",
       "35        N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>School</th>\n      <th>Grade</th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>1</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Changqiang You</td>\n      <td>Male</td>\n      <td>70.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>Fudan University</td>\n      <td>Sophomore</td>\n      <td>Gaojuan You</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>10</th>\n      <td>Shanghai Jiao Tong University</td>\n      <td>Freshman</td>\n      <td>Xiaopeng Zhou</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>18</th>\n      <td>Tsinghua University</td>\n      <td>Senior</td>\n      <td>Xiaofeng Sun</td>\n      <td>Male</td>\n      <td>71.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>35</th>\n      <td>Peking University</td>\n      <td>Freshman</td>\n      <td>Gaoli Zhao</td>\n      <td>Male</td>\n      <td>78.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 42
    }
   ],
   "source": [
    "low, high =70, 80\n",
    "df.query('Weight.between(@low, @high)').head()"
   ]
  },
  {
   "source": [
    "### 6. 随机抽样\n",
    "\n",
    "如果把`DataFrame`的每一行看作一个样本，或把每一列看作一个特征，再把整个`DataFrame`看作总体，想要对样本或特征进行随机抽样就可以用`sample`函数。有时在拿到大型数据集后，想要对统计特征进行计算来了解数据的大致分布，但是这很费时间。同时，由于许多统计特征在等概率不放回的简单随机抽样条件下，是总体统计特征的无偏估计，比如样本均值和总体均值，那么就可以先从整张表中抽出一部分来做近似估计。\n",
    "\n",
    "`sample`函数中的主要参数为`n, axis, frac, replace, weights`，前三个分别是指抽样数量、抽样的方向（0为行、1为列）和抽样比例（0.3则为从总体中抽出30%的样本）。\n",
    "\n",
    "`replace`和`weights`分别是指是否放回和每个样本的抽样相对概率，当`replace = True`则表示有放回抽样。例如，对下面构造的`df_sample`以`value`值的相对大小为抽样概率进行有放回抽样，抽样数量为3。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "  id  value\n",
       "0  a      1\n",
       "1  b      2\n",
       "2  c      3\n",
       "3  d      4\n",
       "4  e     90"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>id</th>\n      <th>value</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>a</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>b</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>c</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>d</td>\n      <td>4</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>e</td>\n      <td>90</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 43
    }
   ],
   "source": [
    "df_sample = pd.DataFrame({'id': list('abcde'), 'value': [1, 2, 3, 4, 90]})\n",
    "df_sample"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "  id  value\n",
       "4  e     90\n",
       "4  e     90\n",
       "4  e     90"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>id</th>\n      <th>value</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>4</th>\n      <td>e</td>\n      <td>90</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>e</td>\n      <td>90</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>e</td>\n      <td>90</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 44
    }
   ],
   "source": [
    "df_sample.sample(3, replace = True, weights = df_sample.value)"
   ]
  },
  {
   "source": [
    "## 二、多级索引\n",
    "### 1. 多级索引及其表的结构\n",
    "\n",
    "为了更加清晰地说明具有多级索引的`DataFrame`结构，下面新构造一张表，读者可以忽略这里的构造方法，它们将会在第4小节被更详细地讲解。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Indicator       Height                           Weight                   \\\n",
       "Grade         Freshman Senior Sophomore Junior Freshman Senior Sophomore   \n",
       "School Gender                                                              \n",
       "A      Female    171.8  165.0     167.9  174.2     60.6   55.1      63.3   \n",
       "       Male      172.3  158.1     167.8  162.2     71.2   71.0      63.1   \n",
       "B      Female    162.5  165.1     163.7  170.3     59.8   57.9      56.5   \n",
       "       Male      166.8  163.6     165.2  164.7     62.5   62.8      58.7   \n",
       "C      Female    170.5  162.0     164.6  158.7     56.9   63.9      60.5   \n",
       "       Male      150.2  166.3     167.3  159.3     62.4   59.1      64.9   \n",
       "D      Female    174.3  155.7     163.2  162.1     65.3   66.5      61.8   \n",
       "       Male      170.7  170.3     163.8  164.9     61.6   63.2      60.9   \n",
       "\n",
       "Indicator             \n",
       "Grade         Junior  \n",
       "School Gender         \n",
       "A      Female   65.8  \n",
       "       Male     63.5  \n",
       "B      Female   74.8  \n",
       "       Male     68.9  \n",
       "C      Female   66.9  \n",
       "       Male     67.1  \n",
       "D      Female   63.2  \n",
       "       Male     56.4  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th>Indicator</th>\n      <th colspan=\"4\" halign=\"left\">Height</th>\n      <th colspan=\"4\" halign=\"left\">Weight</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th>Grade</th>\n      <th>Freshman</th>\n      <th>Senior</th>\n      <th>Sophomore</th>\n      <th>Junior</th>\n      <th>Freshman</th>\n      <th>Senior</th>\n      <th>Sophomore</th>\n      <th>Junior</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Gender</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">A</th>\n      <th>Female</th>\n      <td>171.8</td>\n      <td>165.0</td>\n      <td>167.9</td>\n      <td>174.2</td>\n      <td>60.6</td>\n      <td>55.1</td>\n      <td>63.3</td>\n      <td>65.8</td>\n    </tr>\n    <tr>\n      <th>Male</th>\n      <td>172.3</td>\n      <td>158.1</td>\n      <td>167.8</td>\n      <td>162.2</td>\n      <td>71.2</td>\n      <td>71.0</td>\n      <td>63.1</td>\n      <td>63.5</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">B</th>\n      <th>Female</th>\n      <td>162.5</td>\n      <td>165.1</td>\n      <td>163.7</td>\n      <td>170.3</td>\n      <td>59.8</td>\n      <td>57.9</td>\n      <td>56.5</td>\n      <td>74.8</td>\n    </tr>\n    <tr>\n      <th>Male</th>\n      <td>166.8</td>\n      <td>163.6</td>\n      <td>165.2</td>\n      <td>164.7</td>\n      <td>62.5</td>\n      <td>62.8</td>\n      <td>58.7</td>\n      <td>68.9</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">C</th>\n      <th>Female</th>\n      <td>170.5</td>\n      <td>162.0</td>\n      <td>164.6</td>\n      <td>158.7</td>\n      <td>56.9</td>\n      <td>63.9</td>\n      <td>60.5</td>\n      <td>66.9</td>\n    </tr>\n    <tr>\n      <th>Male</th>\n      <td>150.2</td>\n      <td>166.3</td>\n      <td>167.3</td>\n      <td>159.3</td>\n      <td>62.4</td>\n      <td>59.1</td>\n      <td>64.9</td>\n      <td>67.1</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">D</th>\n      <th>Female</th>\n      <td>174.3</td>\n      <td>155.7</td>\n      <td>163.2</td>\n      <td>162.1</td>\n      <td>65.3</td>\n      <td>66.5</td>\n      <td>61.8</td>\n      <td>63.2</td>\n    </tr>\n    <tr>\n      <th>Male</th>\n      <td>170.7</td>\n      <td>170.3</td>\n      <td>163.8</td>\n      <td>164.9</td>\n      <td>61.6</td>\n      <td>63.2</td>\n      <td>60.9</td>\n      <td>56.4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 45
    }
   ],
   "source": [
    "np.random.seed(0)\n",
    "multi_index = pd.MultiIndex.from_product([list('ABCD'), df.Gender.unique()], names=('School', 'Gender'))\n",
    "multi_column = pd.MultiIndex.from_product([['Height', 'Weight'], df.Grade.unique()], names=('Indicator', 'Grade'))\n",
    "df_multi = pd.DataFrame(np.c_[(np.random.randn(8,4)*5 + 163).tolist(), (np.random.randn(8,4)*5 + 65).tolist()],\n",
    "                        index = multi_index, columns = multi_column).round(1)\n",
    "df_multi"
   ]
  },
  {
   "source": [
    "下图通过颜色区分，标记了`DataFrame`的结构。与单层索引的表一样，具备元素值、行索引和列索引三个部分。其中，这里的行索引和列索引都是`MultiIndex`类型，只不过**索引中的一个元素是元组**而不是单层索引中的标量。例如，行索引的第四个元素为`(\"B\", \"Male\")`，列索引的第二个元素为`(\"Height\", \"Senior\")`，这里需要注意，外层连续出现相同的值时，第一次之后出现的会被隐藏显示，使结果的可读性增强。\n",
    "\n",
    "<img src=\"../source/_static/multi_index.png\" width=\"50%\">\n",
    "\n",
    "与单层索引类似，`MultiIndex`也具有名字属性，图中的`School`和`Gender`分别对应了表的第一层和第二层行索引的名字，`Indicator`和`Grade`分别对应了第一层和第二层列索引的名字。\n",
    "\n",
    "索引的名字和值属性分别可以通过`names`和`values`获得："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "FrozenList(['School', 'Gender'])"
      ]
     },
     "metadata": {},
     "execution_count": 46
    }
   ],
   "source": [
    "df_multi.index.names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "FrozenList(['Indicator', 'Grade'])"
      ]
     },
     "metadata": {},
     "execution_count": 47
    }
   ],
   "source": [
    "df_multi.columns.names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([('A', 'Female'), ('A', 'Male'), ('B', 'Female'), ('B', 'Male'),\n",
       "       ('C', 'Female'), ('C', 'Male'), ('D', 'Female'), ('D', 'Male')],\n",
       "      dtype=object)"
      ]
     },
     "metadata": {},
     "execution_count": 48
    }
   ],
   "source": [
    "df_multi.index.values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([('Height', 'Freshman'), ('Height', 'Senior'),\n",
       "       ('Height', 'Sophomore'), ('Height', 'Junior'),\n",
       "       ('Weight', 'Freshman'), ('Weight', 'Senior'),\n",
       "       ('Weight', 'Sophomore'), ('Weight', 'Junior')], dtype=object)"
      ]
     },
     "metadata": {},
     "execution_count": 49
    }
   ],
   "source": [
    "df_multi.columns.values"
   ]
  },
  {
   "source": [
    "如果想要得到某一层的索引，则需要通过`get_level_values`获得："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Index(['A', 'A', 'B', 'B', 'C', 'C', 'D', 'D'], dtype='object', name='School')"
      ]
     },
     "metadata": {},
     "execution_count": 50
    }
   ],
   "source": [
    "df_multi.index.get_level_values(0)"
   ]
  },
  {
   "source": [
    "但对于索引而言，无论是单层还是多层，用户都无法通过`index_obj[0] = item`的方式来修改元素，也不能通过`index_name[0] = new_name`的方式来修改名字，关于如何修改这些属性的话题将在第三节被讨论。\n",
    "\n",
    "### 2. 多级索引中的loc索引器\n",
    "\n",
    "熟悉了结构后，现在回到原表，将学校和年级设为索引，此时的行为多级索引，列为单级索引，由于默认状态的列索引不含名字，因此对应于刚刚图中`Indicator`和`Grade`的索引名位置是空缺的。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                                   Name  Gender  Weight  \\\n",
       "School                        Grade                                       \n",
       "Shanghai Jiao Tong University Freshman     Gaopeng Yang  Female    46.0   \n",
       "Peking University             Freshman   Changqiang You    Male    70.0   \n",
       "Shanghai Jiao Tong University Senior            Mei Sun    Male    89.0   \n",
       "Fudan University              Sophomore    Xiaojuan Sun  Female    41.0   \n",
       "                              Sophomore     Gaojuan You    Male    74.0   \n",
       "\n",
       "                                        Transfer  \n",
       "School                        Grade               \n",
       "Shanghai Jiao Tong University Freshman         N  \n",
       "Peking University             Freshman         N  \n",
       "Shanghai Jiao Tong University Senior           N  \n",
       "Fudan University              Sophomore        N  \n",
       "                              Sophomore        N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Shanghai Jiao Tong University</th>\n      <th>Freshman</th>\n      <td>Gaopeng Yang</td>\n      <td>Female</td>\n      <td>46.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Peking University</th>\n      <th>Freshman</th>\n      <td>Changqiang You</td>\n      <td>Male</td>\n      <td>70.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Shanghai Jiao Tong University</th>\n      <th>Senior</th>\n      <td>Mei Sun</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">Fudan University</th>\n      <th>Sophomore</th>\n      <td>Xiaojuan Sun</td>\n      <td>Female</td>\n      <td>41.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Sophomore</th>\n      <td>Gaojuan You</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 51
    }
   ],
   "source": [
    "df_multi = df.set_index(['School', 'Grade'])\n",
    "df_multi.head()"
   ]
  },
  {
   "source": [
    "由于多级索引中的单个元素以元组为单位，因此之前在第一节介绍的 ``loc`` 和 ``iloc`` 方法完全可以照搬，只需把标量的位置替换成对应的元组。\n",
    "\n",
    "当传入元组列表或单个元组或返回前二者的函数时，需要先进行索引排序以避免性能警告："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "pandas.errors.PerformanceWarning('indexing past lexsort depth may impact performance.')"
      ]
     },
     "metadata": {},
     "execution_count": 52
    }
   ],
   "source": [
    "with warnings.catch_warnings():\n",
    "    warnings.filterwarnings('error')\n",
    "    try:\n",
    "        df_multi.loc[('Fudan University', 'Junior')].head()\n",
    "    except Warning as w:\n",
    "        Warning_Msg = w\n",
    "Warning_Msg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                  Name  Gender  Weight Transfer\n",
       "School           Grade                                         \n",
       "Fudan University Junior      Yanli You  Female    48.0        N\n",
       "                 Junior  Chunqiang Chu    Male    72.0        N\n",
       "                 Junior   Changfeng Lv    Male    76.0        N\n",
       "                 Junior     Yanjuan Lv  Female    49.0      NaN\n",
       "                 Junior  Gaoqiang Zhou  Female    43.0        N"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">Fudan University</th>\n      <th>Junior</th>\n      <td>Yanli You</td>\n      <td>Female</td>\n      <td>48.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Chunqiang Chu</td>\n      <td>Male</td>\n      <td>72.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Changfeng Lv</td>\n      <td>Male</td>\n      <td>76.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Yanjuan Lv</td>\n      <td>Female</td>\n      <td>49.0</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Gaoqiang Zhou</td>\n      <td>Female</td>\n      <td>43.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 53
    }
   ],
   "source": [
    "df_sorted = df_multi.sort_index()\n",
    "df_sorted.loc[('Fudan University', 'Junior')].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                    Name  Gender  Weight Transfer\n",
       "School           Grade                                           \n",
       "Fudan University Senior  Chengpeng Zheng  Female    38.0        N\n",
       "                 Senior        Feng Zhou  Female    47.0        N\n",
       "                 Senior        Gaomei Lv  Female    34.0        N\n",
       "                 Senior        Chunli Lv  Female    56.0        N\n",
       "                 Senior   Chengpeng Zhou    Male    81.0        N"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">Fudan University</th>\n      <th>Senior</th>\n      <td>Chengpeng Zheng</td>\n      <td>Female</td>\n      <td>38.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Feng Zhou</td>\n      <td>Female</td>\n      <td>47.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Gaomei Lv</td>\n      <td>Female</td>\n      <td>34.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Chunli Lv</td>\n      <td>Female</td>\n      <td>56.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Chengpeng Zhou</td>\n      <td>Male</td>\n      <td>81.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 54
    }
   ],
   "source": [
    "df_sorted.loc[[('Fudan University', 'Senior'), ('Shanghai Jiao Tong University', 'Freshman')]].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                     Name Gender  Weight Transfer\n",
       "School           Grade                                           \n",
       "Fudan University Freshman       Feng Wang   Male    74.0        N\n",
       "                 Junior     Chunqiang Chu   Male    72.0        N\n",
       "                 Junior      Changfeng Lv   Male    76.0        N\n",
       "                 Senior    Chengpeng Zhou   Male    81.0        N\n",
       "                 Senior    Chengpeng Qian   Male    73.0        Y"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">Fudan University</th>\n      <th>Freshman</th>\n      <td>Feng Wang</td>\n      <td>Male</td>\n      <td>74.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Chunqiang Chu</td>\n      <td>Male</td>\n      <td>72.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Changfeng Lv</td>\n      <td>Male</td>\n      <td>76.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Chengpeng Zhou</td>\n      <td>Male</td>\n      <td>81.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Chengpeng Qian</td>\n      <td>Male</td>\n      <td>73.0</td>\n      <td>Y</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 55
    }
   ],
   "source": [
    "df_sorted.loc[df_sorted.Weight > 70].head() # 布尔列表也是可用的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                  Name  Gender  Weight Transfer\n",
       "School           Grade                                         \n",
       "Fudan University Junior      Yanli You  Female    48.0        N\n",
       "                 Junior  Chunqiang Chu    Male    72.0        N\n",
       "                 Junior   Changfeng Lv    Male    76.0        N\n",
       "                 Junior     Yanjuan Lv  Female    49.0      NaN\n",
       "                 Junior  Gaoqiang Zhou  Female    43.0        N"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">Fudan University</th>\n      <th>Junior</th>\n      <td>Yanli You</td>\n      <td>Female</td>\n      <td>48.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Chunqiang Chu</td>\n      <td>Male</td>\n      <td>72.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Changfeng Lv</td>\n      <td>Male</td>\n      <td>76.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Yanjuan Lv</td>\n      <td>Female</td>\n      <td>49.0</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Gaoqiang Zhou</td>\n      <td>Female</td>\n      <td>43.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 56
    }
   ],
   "source": [
    "df_sorted.loc[lambda x:('Fudan University','Junior')].head()"
   ]
  },
  {
   "source": [
    "当使用切片时需要注意，在单级索引中只要切片端点元素是唯一的，那么就可以进行切片，但在多级索引中，无论元组在索引中是否重复出现，都必须经过排序才能使用切片，否则报错："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "pandas.errors.UnsortedIndexError('Key length (2) was greater than MultiIndex lexsort depth (0)')"
      ]
     },
     "metadata": {},
     "execution_count": 57
    }
   ],
   "source": [
    "try:\n",
    "    df_multi.loc[('Fudan University', 'Senior'):].head()\n",
    "except Exception as e:\n",
    "    Err_Msg = e\n",
    "Err_Msg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                    Name  Gender  Weight Transfer\n",
       "School           Grade                                           \n",
       "Fudan University Senior  Chengpeng Zheng  Female    38.0        N\n",
       "                 Senior        Feng Zhou  Female    47.0        N\n",
       "                 Senior        Gaomei Lv  Female    34.0        N\n",
       "                 Senior        Chunli Lv  Female    56.0        N\n",
       "                 Senior   Chengpeng Zhou    Male    81.0        N"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">Fudan University</th>\n      <th>Senior</th>\n      <td>Chengpeng Zheng</td>\n      <td>Female</td>\n      <td>38.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Feng Zhou</td>\n      <td>Female</td>\n      <td>47.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Gaomei Lv</td>\n      <td>Female</td>\n      <td>34.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Chunli Lv</td>\n      <td>Female</td>\n      <td>56.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Chengpeng Zhou</td>\n      <td>Male</td>\n      <td>81.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 58
    }
   ],
   "source": [
    "df_sorted.loc[('Fudan University', 'Senior'):].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                                   Name  Gender  Weight  \\\n",
       "School                        Grade                                       \n",
       "Shanghai Jiao Tong University Freshman     Gaopeng Yang  Female    46.0   \n",
       "Peking University             Freshman   Changqiang You    Male    70.0   \n",
       "Shanghai Jiao Tong University Senior            Mei Sun    Male    89.0   \n",
       "Fudan University              Sophomore    Xiaojuan Sun  Female    41.0   \n",
       "Tsinghua University           Freshman      Xiaoli Qian  Female    51.0   \n",
       "\n",
       "                                        Transfer  \n",
       "School                        Grade               \n",
       "Shanghai Jiao Tong University Freshman         N  \n",
       "Peking University             Freshman         N  \n",
       "Shanghai Jiao Tong University Senior           N  \n",
       "Fudan University              Sophomore        N  \n",
       "Tsinghua University           Freshman         N  "
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>Shanghai Jiao Tong University</th>\n      <th>Freshman</th>\n      <td>Gaopeng Yang</td>\n      <td>Female</td>\n      <td>46.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Peking University</th>\n      <th>Freshman</th>\n      <td>Changqiang You</td>\n      <td>Male</td>\n      <td>70.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Shanghai Jiao Tong University</th>\n      <th>Senior</th>\n      <td>Mei Sun</td>\n      <td>Male</td>\n      <td>89.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Fudan University</th>\n      <th>Sophomore</th>\n      <td>Xiaojuan Sun</td>\n      <td>Female</td>\n      <td>41.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Tsinghua University</th>\n      <th>Freshman</th>\n      <td>Xiaoli Qian</td>\n      <td>Female</td>\n      <td>51.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 59
    }
   ],
   "source": [
    "df_unique = df.drop_duplicates(subset=['School','Grade']).set_index(['School', 'Grade'])\n",
    "df_unique.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "pandas.errors.UnsortedIndexError('Key length (2) was greater than MultiIndex lexsort depth (0)')"
      ]
     },
     "metadata": {},
     "execution_count": 60
    }
   ],
   "source": [
    "try:\n",
    "    df_unique.loc[('Fudan University', 'Senior'):].head()\n",
    "except Exception as e:\n",
    "    Err_Msg = e\n",
    "Err_Msg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                        Name  Gender  Weight Transfer\n",
       "School            Grade                                              \n",
       "Fudan University  Senior     Chengpeng Zheng  Female    38.0        N\n",
       "                  Sophomore     Xiaojuan Sun  Female    41.0        N\n",
       "Peking University Freshman    Changqiang You    Male    70.0        N\n",
       "                  Junior             Juan Xu  Female     NaN        N\n",
       "                  Senior          Changli Lv  Female    41.0        N"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">Fudan University</th>\n      <th>Senior</th>\n      <td>Chengpeng Zheng</td>\n      <td>Female</td>\n      <td>38.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Sophomore</th>\n      <td>Xiaojuan Sun</td>\n      <td>Female</td>\n      <td>41.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th rowspan=\"3\" valign=\"top\">Peking University</th>\n      <th>Freshman</th>\n      <td>Changqiang You</td>\n      <td>Male</td>\n      <td>70.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Juan Xu</td>\n      <td>Female</td>\n      <td>NaN</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Senior</th>\n      <td>Changli Lv</td>\n      <td>Female</td>\n      <td>41.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 61
    }
   ],
   "source": [
    "df_unique.sort_index().loc[('Fudan University', 'Senior'):].head()"
   ]
  },
  {
   "source": [
    "此外，在多级索引中的元组有一种特殊的用法，可以对多层的元素进行交叉组合后索引，但同时需要指定`loc`的列，全选则用`:`表示。其中，每一层需要选中的元素用列表存放，传入`loc`的形式为`[(level_0_list, level_1_list), cols]`。例如，想要得到所有北大和复旦的大二大三学生，可以如下写出："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                     Name  Gender  Weight Transfer\n",
       "School            Grade                                           \n",
       "Peking University Sophomore   Changmei Xu  Female    43.0        N\n",
       "                  Sophomore  Xiaopeng Qin    Male     NaN        N\n",
       "                  Sophomore        Mei Xu  Female    39.0        N\n",
       "                  Sophomore   Xiaoli Zhou  Female    55.0        N\n",
       "                  Sophomore      Peng Han  Female    34.0      NaN"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">Peking University</th>\n      <th>Sophomore</th>\n      <td>Changmei Xu</td>\n      <td>Female</td>\n      <td>43.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Sophomore</th>\n      <td>Xiaopeng Qin</td>\n      <td>Male</td>\n      <td>NaN</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Sophomore</th>\n      <td>Mei Xu</td>\n      <td>Female</td>\n      <td>39.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Sophomore</th>\n      <td>Xiaoli Zhou</td>\n      <td>Female</td>\n      <td>55.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Sophomore</th>\n      <td>Peng Han</td>\n      <td>Female</td>\n      <td>34.0</td>\n      <td>NaN</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 62
    }
   ],
   "source": [
    "res = df_multi.loc[(['Peking University', 'Fudan University'], ['Sophomore', 'Junior']), :]\n",
    "res.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "(33, 4)"
      ]
     },
     "metadata": {},
     "execution_count": 63
    }
   ],
   "source": [
    "res.shape"
   ]
  },
  {
   "source": [
    "下面的语句和上面类似，但仍然传入的是元素（这里为元组）的列表，它们的意义是不同的，表示的是选出北大的大三学生和复旦的大二学生："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "                                   Name  Gender  Weight Transfer\n",
       "School            Grade                                         \n",
       "Peking University Junior        Juan Xu  Female     NaN        N\n",
       "                  Junior  Changjuan You  Female    47.0        N\n",
       "                  Junior       Gaoli Xu  Female    48.0        N\n",
       "                  Junior   Gaoquan Zhou    Male    70.0        N\n",
       "                  Junior      Qiang You  Female    56.0        N"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Name</th>\n      <th>Gender</th>\n      <th>Weight</th>\n      <th>Transfer</th>\n    </tr>\n    <tr>\n      <th>School</th>\n      <th>Grade</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">Peking University</th>\n      <th>Junior</th>\n      <td>Juan Xu</td>\n      <td>Female</td>\n      <td>NaN</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Changjuan You</td>\n      <td>Female</td>\n      <td>47.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Gaoli Xu</td>\n      <td>Female</td>\n      <td>48.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Gaoquan Zhou</td>\n      <td>Male</td>\n      <td>70.0</td>\n      <td>N</td>\n    </tr>\n    <tr>\n      <th>Junior</th>\n      <td>Qiang You</td>\n      <td>Female</td>\n      <td>56.0</td>\n      <td>N</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 64
    }
   ],
   "source": [
    "res = df_multi.loc[[('Peking University', 'Junior'), ('Fudan University', 'Sophomore')]]\n",
    "res.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "(16, 4)"
      ]
     },
     "metadata": {},
     "execution_count": 65
    }
   ],
   "source": [
    "res.shape"
   ]
  },
  {
   "source": [
    "### 3. IndexSlice对象\n",
    "\n",
    "前面介绍的方法，即使在索引不重复的时候，也只能对元组整体进行切片，而不能对每层进行切片，也不允许将切片和布尔列表混合使用，引入`IndexSlice`对象就能解决这个问题。`Slice`对象一共有两种形式，第一种为`loc[idx[*,*]]`型，第二种为`loc[idx[*,*],idx[*,*]]`型，下面将进行介绍。为了方便演示，下面构造一个**索引不重复的**`DataFrame`："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big          D        E        F      \n",
       "Small        d  e  f  d  e  f  d  e  f\n",
       "Upper Lower                           \n",
       "A     a      3  6 -9 -6 -6 -2  0  9 -5\n",
       "      b     -3  3 -8 -3 -2  5  8 -4  4\n",
       "      c     -1  0  7 -4  6  6 -9  9 -6\n",
       "B     a      8  5 -2 -9 -8  0 -9  1 -6\n",
       "      b      2  9 -7 -9 -9 -5 -4 -3 -1\n",
       "      c      8  6 -5  0  1 -8 -8 -2  0\n",
       "C     a     -6 -3  2  5  9 -9  5 -6  3\n",
       "      b      1  2 -5 -3 -5  6 -6  3 -5\n",
       "      c     -1  5  6 -6  6  4  7  8 -4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"3\" halign=\"left\">D</th>\n      <th colspan=\"3\" halign=\"left\">E</th>\n      <th colspan=\"3\" halign=\"left\">F</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th>Small</th>\n      <th>d</th>\n      <th>e</th>\n      <th>f</th>\n      <th>d</th>\n      <th>e</th>\n      <th>f</th>\n      <th>d</th>\n      <th>e</th>\n      <th>f</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"3\" valign=\"top\">A</th>\n      <th>a</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n      <td>-5</td>\n    </tr>\n    <tr>\n      <th>b</th>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n      <td>-4</td>\n      <td>4</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n    </tr>\n    <tr>\n      <th rowspan=\"3\" valign=\"top\">B</th>\n      <th>a</th>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n    </tr>\n    <tr>\n      <th>b</th>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n      <td>-9</td>\n      <td>-5</td>\n      <td>-4</td>\n      <td>-3</td>\n      <td>-1</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <td>8</td>\n      <td>6</td>\n      <td>-5</td>\n      <td>0</td>\n      <td>1</td>\n      <td>-8</td>\n      <td>-8</td>\n      <td>-2</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th rowspan=\"3\" valign=\"top\">C</th>\n      <th>a</th>\n      <td>-6</td>\n      <td>-3</td>\n      <td>2</td>\n      <td>5</td>\n      <td>9</td>\n      <td>-9</td>\n      <td>5</td>\n      <td>-6</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>b</th>\n      <td>1</td>\n      <td>2</td>\n      <td>-5</td>\n      <td>-3</td>\n      <td>-5</td>\n      <td>6</td>\n      <td>-6</td>\n      <td>3</td>\n      <td>-5</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <td>-1</td>\n      <td>5</td>\n      <td>6</td>\n      <td>-6</td>\n      <td>6</td>\n      <td>4</td>\n      <td>7</td>\n      <td>8</td>\n      <td>-4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 66
    }
   ],
   "source": [
    "np.random.seed(0)\n",
    "L1,L2 = ['A','B','C'],['a','b','c']\n",
    "mul_index1 = pd.MultiIndex.from_product([L1,L2],names=('Upper', 'Lower'))\n",
    "L3,L4 = ['D','E','F'],['d','e','f']\n",
    "mul_index2 = pd.MultiIndex.from_product([L3,L4],names=('Big', 'Small'))\n",
    "df_ex = pd.DataFrame(np.random.randint(-9,10,(9,9)), index=mul_index1, columns=mul_index2)\n",
    "df_ex"
   ]
  },
  {
   "source": [
    "为了使用`silce`对象，先要进行定义："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [],
   "source": [
    "idx = pd.IndexSlice"
   ]
  },
  {
   "source": [
    "【a】`loc[idx[*,*]]`型\n",
    "\n",
    "这种情况并不能进行多层分别切片，前一个`*`表示行的选择，后一个`*`表示列的选择，与单纯的`loc`是类似的："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big          D  E        F      \n",
       "Small        f  d  e  f  d  e  f\n",
       "Upper Lower                     \n",
       "C     a      2  5  9 -9  5 -6  3\n",
       "      b     -5 -3 -5  6 -6  3 -5\n",
       "      c      6 -6  6  4  7  8 -4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th>Big</th>\n      <th>D</th>\n      <th colspan=\"3\" halign=\"left\">E</th>\n      <th colspan=\"3\" halign=\"left\">F</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th>Small</th>\n      <th>f</th>\n      <th>d</th>\n      <th>e</th>\n      <th>f</th>\n      <th>d</th>\n      <th>e</th>\n      <th>f</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"3\" valign=\"top\">C</th>\n      <th>a</th>\n      <td>2</td>\n      <td>5</td>\n      <td>9</td>\n      <td>-9</td>\n      <td>5</td>\n      <td>-6</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>b</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>-5</td>\n      <td>6</td>\n      <td>-6</td>\n      <td>3</td>\n      <td>-5</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <td>6</td>\n      <td>-6</td>\n      <td>6</td>\n      <td>4</td>\n      <td>7</td>\n      <td>8</td>\n      <td>-4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 68
    }
   ],
   "source": [
    "df_ex.loc[idx['C':, ('D', 'f'):]]"
   ]
  },
  {
   "source": [
    "另外，也支持布尔序列的索引："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big          D     F\n",
       "Small        d  e  e\n",
       "Upper Lower         \n",
       "A     a      3  6  9\n",
       "      b     -3  3 -4\n",
       "      c     -1  0  9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"2\" halign=\"left\">D</th>\n      <th>F</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th>Small</th>\n      <th>d</th>\n      <th>e</th>\n      <th>e</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"3\" valign=\"top\">A</th>\n      <th>a</th>\n      <td>3</td>\n      <td>6</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>b</th>\n      <td>-3</td>\n      <td>3</td>\n      <td>-4</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <td>-1</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 69
    }
   ],
   "source": [
    "df_ex.loc[idx[:'A', lambda x:x.sum()>0]] # 列和大于0"
   ]
  },
  {
   "source": [
    "【b】`loc[idx[*,*],idx[*,*]]`型\n",
    "\n",
    "这种情况能够分层进行切片，前一个`idx`指代的是行索引，后一个是列索引。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big          E     F   \n",
       "Small        e  f  e  f\n",
       "Upper Lower            \n",
       "A     b     -2  5 -4  4\n",
       "      c      6  6  9 -6"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"2\" halign=\"left\">E</th>\n      <th colspan=\"2\" halign=\"left\">F</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th>Small</th>\n      <th>e</th>\n      <th>f</th>\n      <th>e</th>\n      <th>f</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">A</th>\n      <th>b</th>\n      <td>-2</td>\n      <td>5</td>\n      <td>-4</td>\n      <td>4</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <td>6</td>\n      <td>6</td>\n      <td>9</td>\n      <td>-6</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 70
    }
   ],
   "source": [
    "df_ex.loc[idx[:'A', 'b':], idx['E':, 'e':]]"
   ]
  },
  {
   "source": [
    "但需要注意的是，此时不支持使用函数："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "KeyError(<function __main__.<lambda>(x)>)"
      ]
     },
     "metadata": {},
     "execution_count": 71
    }
   ],
   "source": [
    "try:\n",
    "    df_ex.loc[idx[:'A', lambda x: 'b'], idx['E':, 'e':]]\n",
    "except Exception as e:\n",
    "    Err_Msg = e\n",
    "Err_Msg"
   ]
  },
  {
   "source": [
    "### 4. 多级索引的构造\n",
    "\n",
    "前面提到了多级索引表的结构和切片，那么除了使用`set_index`之外，如何自己构造多级索引呢？常用的有`from_tuples, from_arrays, from_product`三种方法，它们都是`pd.MultiIndex`对象下的函数。\n",
    "\n",
    "`from_tuples`指根据传入由元组组成的列表进行构造："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "MultiIndex([('a', 'cat'),\n",
       "            ('a', 'dog'),\n",
       "            ('b', 'cat'),\n",
       "            ('b', 'dog')],\n",
       "           names=['First', 'Second'])"
      ]
     },
     "metadata": {},
     "execution_count": 72
    }
   ],
   "source": [
    "my_tuple = [('a','cat'),('a','dog'),('b','cat'),('b','dog')]\n",
    "pd.MultiIndex.from_tuples(my_tuple, names=['First','Second'])"
   ]
  },
  {
   "source": [
    "`from_arrays`指根据传入列表中，对应层的列表进行构造："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "MultiIndex([('a', 'cat'),\n",
       "            ('a', 'dog'),\n",
       "            ('b', 'cat'),\n",
       "            ('b', 'dog')],\n",
       "           names=['First', 'Second'])"
      ]
     },
     "metadata": {},
     "execution_count": 73
    }
   ],
   "source": [
    "my_array = [list('aabb'), ['cat', 'dog']*2]\n",
    "pd.MultiIndex.from_arrays(my_array, names=['First','Second'])"
   ]
  },
  {
   "source": [
    "`from_product`指根据给定多个列表的笛卡尔积进行构造："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "MultiIndex([('a', 'cat'),\n",
       "            ('a', 'dog'),\n",
       "            ('b', 'cat'),\n",
       "            ('b', 'dog')],\n",
       "           names=['First', 'Second'])"
      ]
     },
     "metadata": {},
     "execution_count": 74
    }
   ],
   "source": [
    "my_list1 = ['a','b']\n",
    "my_list2 = ['cat','dog']\n",
    "pd.MultiIndex.from_product([my_list1, my_list2], names=['First','Second'])"
   ]
  },
  {
   "source": [
    "## 三、索引的常用方法\n",
    "### 1. 索引层的交换和删除\n",
    "为了方便理解交换的过程，这里构造一个三级索引的例子："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big                 C               D            \n",
       "Small               c       d       c       d    \n",
       "Other             cat dog cat dog cat dog cat dog\n",
       "Upper Lower Extra                                \n",
       "A     a     alpha   3   6  -9  -6  -6  -2   0   9\n",
       "            beta   -5  -3   3  -8  -3  -2   5   8\n",
       "      b     alpha  -4   4  -1   0   7  -4   6   6\n",
       "            beta   -9   9  -6   8   5  -2  -9  -8\n",
       "B     a     alpha   0  -9   1  -6   2   9  -7  -9\n",
       "            beta   -9  -5  -4  -3  -1   8   6  -5\n",
       "      b     alpha   0   1  -8  -8  -2   0  -6  -3\n",
       "            beta    2   5   9  -9   5  -6   3   1"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th>Extra</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">A</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>alpha</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>alpha</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">B</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>alpha</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>-5</td>\n      <td>-4</td>\n      <td>-3</td>\n      <td>-1</td>\n      <td>8</td>\n      <td>6</td>\n      <td>-5</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>alpha</th>\n      <td>0</td>\n      <td>1</td>\n      <td>-8</td>\n      <td>-8</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>-6</td>\n      <td>-3</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>2</td>\n      <td>5</td>\n      <td>9</td>\n      <td>-9</td>\n      <td>5</td>\n      <td>-6</td>\n      <td>3</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 75
    }
   ],
   "source": [
    "np.random.seed(0)\n",
    "L1,L2,L3 = ['A','B'],['a','b'],['alpha','beta']\n",
    "mul_index1 = pd.MultiIndex.from_product([L1,L2,L3], names=('Upper', 'Lower','Extra'))\n",
    "L4,L5,L6 = ['C','D'],['c','d'],['cat','dog']\n",
    "mul_index2 = pd.MultiIndex.from_product([L4,L5,L6], names=('Big', 'Small', 'Other'))\n",
    "df_ex = pd.DataFrame(np.random.randint(-9,10,(8,8)), index=mul_index1,  columns=mul_index2)\n",
    "df_ex"
   ]
  },
  {
   "source": [
    "索引层的交换由`swaplevel`和`reorder_levels`完成，前者只能交换两个层，而后者可以交换任意层，两者都可以指定交换的是轴是哪一个，即行索引或列索引："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Other             cat dog cat dog cat dog cat dog\n",
       "Small               c   c   d   d   c   c   d   d\n",
       "Big                 C   C   C   C   D   D   D   D\n",
       "Upper Lower Extra                                \n",
       "A     a     alpha   3   6  -9  -6  -6  -2   0   9\n",
       "            beta   -5  -3   3  -8  -3  -2   5   8\n",
       "      b     alpha  -4   4  -1   0   7  -4   6   6\n",
       "            beta   -9   9  -6   8   5  -2  -9  -8\n",
       "B     a     alpha   0  -9   1  -6   2   9  -7  -9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Small</th>\n      <th>c</th>\n      <th>c</th>\n      <th>d</th>\n      <th>d</th>\n      <th>c</th>\n      <th>c</th>\n      <th>d</th>\n      <th>d</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th>C</th>\n      <th>C</th>\n      <th>C</th>\n      <th>C</th>\n      <th>D</th>\n      <th>D</th>\n      <th>D</th>\n      <th>D</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th>Extra</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">A</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>alpha</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>alpha</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th>B</th>\n      <th>a</th>\n      <th>alpha</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 76
    }
   ],
   "source": [
    "df_ex.swaplevel(0,2,axis=1).head() # 列索引的第一层和第三层交换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big                 C               D            \n",
       "Small               c       d       c       d    \n",
       "Other             cat dog cat dog cat dog cat dog\n",
       "Extra Upper Lower                                \n",
       "alpha A     a       3   6  -9  -6  -6  -2   0   9\n",
       "beta  A     a      -5  -3   3  -8  -3  -2   5   8\n",
       "alpha A     b      -4   4  -1   0   7  -4   6   6\n",
       "beta  A     b      -9   9  -6   8   5  -2  -9  -8\n",
       "alpha B     a       0  -9   1  -6   2   9  -7  -9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th>Extra</th>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>alpha</th>\n      <th>A</th>\n      <th>a</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <th>A</th>\n      <th>a</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th>alpha</th>\n      <th>A</th>\n      <th>b</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <th>A</th>\n      <th>b</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th>alpha</th>\n      <th>B</th>\n      <th>a</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 77
    }
   ],
   "source": [
    "df_ex.reorder_levels([2,0,1],axis=0).head() # 列表数字指代原来索引中的层"
   ]
  },
  {
   "source": [
    "#### 【NOTE】轴之间的索引交换\n",
    "这里只涉及行或列索引内部的交换，不同方向索引之间的交换将在第五章中被讨论。\n",
    "#### 【END】\n",
    "若想要删除某一层的索引，可以使用`droplevel`方法："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big                 C               D            \n",
       "Other             cat dog cat dog cat dog cat dog\n",
       "Upper Lower Extra                                \n",
       "A     a     alpha   3   6  -9  -6  -6  -2   0   9\n",
       "            beta   -5  -3   3  -8  -3  -2   5   8\n",
       "      b     alpha  -4   4  -1   0   7  -4   6   6\n",
       "            beta   -9   9  -6   8   5  -2  -9  -8\n",
       "B     a     alpha   0  -9   1  -6   2   9  -7  -9\n",
       "            beta   -9  -5  -4  -3  -1   8   6  -5\n",
       "      b     alpha   0   1  -8  -8  -2   0  -6  -3\n",
       "            beta    2   5   9  -9   5  -6   3   1"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th>Extra</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">A</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>alpha</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>alpha</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">B</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>alpha</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>-5</td>\n      <td>-4</td>\n      <td>-3</td>\n      <td>-1</td>\n      <td>8</td>\n      <td>6</td>\n      <td>-5</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>alpha</th>\n      <td>0</td>\n      <td>1</td>\n      <td>-8</td>\n      <td>-8</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>-6</td>\n      <td>-3</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>2</td>\n      <td>5</td>\n      <td>9</td>\n      <td>-9</td>\n      <td>5</td>\n      <td>-6</td>\n      <td>3</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 78
    }
   ],
   "source": [
    "df_ex.droplevel(1,axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big     C               D            \n",
       "Small   c       d       c       d    \n",
       "Other cat dog cat dog cat dog cat dog\n",
       "Extra                                \n",
       "alpha   3   6  -9  -6  -6  -2   0   9\n",
       "beta   -5  -3   3  -8  -3  -2   5   8\n",
       "alpha  -4   4  -1   0   7  -4   6   6\n",
       "beta   -9   9  -6   8   5  -2  -9  -8\n",
       "alpha   0  -9   1  -6   2   9  -7  -9\n",
       "beta   -9  -5  -4  -3  -1   8   6  -5\n",
       "alpha   0   1  -8  -8  -2   0  -6  -3\n",
       "beta    2   5   9  -9   5  -6   3   1"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th>Extra</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>alpha</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th>alpha</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th>alpha</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>-5</td>\n      <td>-4</td>\n      <td>-3</td>\n      <td>-1</td>\n      <td>8</td>\n      <td>6</td>\n      <td>-5</td>\n    </tr>\n    <tr>\n      <th>alpha</th>\n      <td>0</td>\n      <td>1</td>\n      <td>-8</td>\n      <td>-8</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>-6</td>\n      <td>-3</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>2</td>\n      <td>5</td>\n      <td>9</td>\n      <td>-9</td>\n      <td>5</td>\n      <td>-6</td>\n      <td>3</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 79
    }
   ],
   "source": [
    "df_ex.droplevel([0,1],axis=0)"
   ]
  },
  {
   "source": [
    "### 2. 索引属性的修改\n",
    "通过`rename_axis`可以对索引层的名字进行修改，常用的修改方式是传入字典的映射："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big                       C               D            \n",
       "Small                     c       d       c       d    \n",
       "Changed_Col             cat dog cat dog cat dog cat dog\n",
       "Changed_row Lower Extra                                \n",
       "A           a     alpha   3   6  -9  -6  -6  -2   0   9\n",
       "                  beta   -5  -3   3  -8  -3  -2   5   8\n",
       "            b     alpha  -4   4  -1   0   7  -4   6   6\n",
       "                  beta   -9   9  -6   8   5  -2  -9  -8\n",
       "B           a     alpha   0  -9   1  -6   2   9  -7  -9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Changed_Col</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th>Changed_row</th>\n      <th>Lower</th>\n      <th>Extra</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">A</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>alpha</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>alpha</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th>B</th>\n      <th>a</th>\n      <th>alpha</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 80
    }
   ],
   "source": [
    "df_ex.rename_axis(index={'Upper':'Changed_row'}, columns={'Other':'Changed_Col'}).head()"
   ]
  },
  {
   "source": [
    "通过`rename`可以对索引的值进行修改，如果是多级索引需要指定修改的层号`level`："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big                     C                       D                \n",
       "Small                   c           d           c           d    \n",
       "Other             not_cat dog not_cat dog not_cat dog not_cat dog\n",
       "Upper Lower Extra                                                \n",
       "A     a     alpha       3   6      -9  -6      -6  -2       0   9\n",
       "            beta       -5  -3       3  -8      -3  -2       5   8\n",
       "      b     alpha      -4   4      -1   0       7  -4       6   6\n",
       "            beta       -9   9      -6   8       5  -2      -9  -8\n",
       "B     a     alpha       0  -9       1  -6       2   9      -7  -9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Other</th>\n      <th>not_cat</th>\n      <th>dog</th>\n      <th>not_cat</th>\n      <th>dog</th>\n      <th>not_cat</th>\n      <th>dog</th>\n      <th>not_cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th>Extra</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">A</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>alpha</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>alpha</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th>B</th>\n      <th>a</th>\n      <th>alpha</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 81
    }
   ],
   "source": [
    "df_ex.rename(columns={'cat':'not_cat'}, level=2).head()"
   ]
  },
  {
   "source": [
    "传入参数也可以是函数，其输入值就是索引元素："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big                 C               D            \n",
       "Small               c       d       c       d    \n",
       "Other             cat dog cat dog cat dog cat dog\n",
       "Upper Lower Extra                                \n",
       "A     a     ALPHA   3   6  -9  -6  -6  -2   0   9\n",
       "            BETA   -5  -3   3  -8  -3  -2   5   8\n",
       "      b     ALPHA  -4   4  -1   0   7  -4   6   6\n",
       "            BETA   -9   9  -6   8   5  -2  -9  -8\n",
       "B     a     ALPHA   0  -9   1  -6   2   9  -7  -9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th>Extra</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">A</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>ALPHA</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>BETA</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>ALPHA</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>BETA</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th>B</th>\n      <th>a</th>\n      <th>ALPHA</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 82
    }
   ],
   "source": [
    "df_ex.rename(index=lambda x:str.upper(x), level=2).head()"
   ]
  },
  {
   "source": [
    "#### 【练一练】\n",
    "尝试在`rename_axis`中使用函数完成与例子中一样的功能，即把`Upper`和`Other`分别替换为`Changed_row`和`Changed_col`。\n",
    "#### 【END】\n",
    "对于整个索引的元素替换，可以利用迭代器实现："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big                 C               D            \n",
       "Small               c       d       c       d    \n",
       "Other             cat dog cat dog cat dog cat dog\n",
       "Upper Lower Extra                                \n",
       "A     a     a       3   6  -9  -6  -6  -2   0   9\n",
       "            b      -5  -3   3  -8  -3  -2   5   8\n",
       "      b     c      -4   4  -1   0   7  -4   6   6\n",
       "            d      -9   9  -6   8   5  -2  -9  -8\n",
       "B     a     e       0  -9   1  -6   2   9  -7  -9\n",
       "            f      -9  -5  -4  -3  -1   8   6  -5\n",
       "      b     g       0   1  -8  -8  -2   0  -6  -3\n",
       "            h       2   5   9  -9   5  -6   3   1"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th>Extra</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">A</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>a</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>b</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>c</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>d</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">B</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>e</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n    <tr>\n      <th>f</th>\n      <td>-9</td>\n      <td>-5</td>\n      <td>-4</td>\n      <td>-3</td>\n      <td>-1</td>\n      <td>8</td>\n      <td>6</td>\n      <td>-5</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>g</th>\n      <td>0</td>\n      <td>1</td>\n      <td>-8</td>\n      <td>-8</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>-6</td>\n      <td>-3</td>\n    </tr>\n    <tr>\n      <th>h</th>\n      <td>2</td>\n      <td>5</td>\n      <td>9</td>\n      <td>-9</td>\n      <td>5</td>\n      <td>-6</td>\n      <td>3</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 83
    }
   ],
   "source": [
    "new_values = iter(list('abcdefgh'))\n",
    "df_ex.rename(index=lambda x:next(new_values), level=2)"
   ]
  },
  {
   "source": [
    "若想要对某个位置的元素进行修改，在单层索引时容易实现，即先取出索引的`values`属性，再给对得到的列表进行修改，最后再对`index`对象重新赋值。但是如果是多级索引的话就有些麻烦，一个解决的方案是先把某一层索引临时转为表的元素，然后再进行修改，最后重新设定为索引，下面一节将介绍这些操作。\n",
    "\n",
    "另外一个需要介绍的函数是`map`，它是定义在`Index`上的方法，与前面`rename`方法中层的函数式用法是类似的，只不过它传入的不是层的标量值，而是直接传入索引的元组，这为用户进行跨层的修改提供了遍历。例如，可以等价地写出上面的字符串转大写的操作："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big                 C               D            \n",
       "Small               c       d       c       d    \n",
       "Other             cat dog cat dog cat dog cat dog\n",
       "Upper Lower Extra                                \n",
       "A     a     ALPHA   3   6  -9  -6  -6  -2   0   9\n",
       "            BETA   -5  -3   3  -8  -3  -2   5   8\n",
       "      b     ALPHA  -4   4  -1   0   7  -4   6   6\n",
       "            BETA   -9   9  -6   8   5  -2  -9  -8\n",
       "B     a     ALPHA   0  -9   1  -6   2   9  -7  -9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n\n    .dataframe thead tr:last-of-type th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n    <tr>\n      <th>Upper</th>\n      <th>Lower</th>\n      <th>Extra</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">A</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>ALPHA</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>BETA</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>ALPHA</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>BETA</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th>B</th>\n      <th>a</th>\n      <th>ALPHA</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 84
    }
   ],
   "source": [
    "df_temp = df_ex.copy()\n",
    "new_idx = df_temp.index.map(lambda x: (x[0], x[1], str.upper(x[2])))\n",
    "df_temp.index = new_idx\n",
    "df_temp.head()"
   ]
  },
  {
   "source": [
    "关于`map`的另一个使用方法是对多级索引的压缩，这在第四章和第五章的一些操作中是有用的："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big         C               D            \n",
       "Small       c       d       c       d    \n",
       "Other     cat dog cat dog cat dog cat dog\n",
       "A-a-alpha   3   6  -9  -6  -6  -2   0   9\n",
       "A-a-beta   -5  -3   3  -8  -3  -2   5   8\n",
       "A-b-alpha  -4   4  -1   0   7  -4   6   6\n",
       "A-b-beta   -9   9  -6   8   5  -2  -9  -8\n",
       "B-a-alpha   0  -9   1  -6   2   9  -7  -9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>A-a-alpha</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>A-a-beta</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th>A-b-alpha</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>A-b-beta</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th>B-a-alpha</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 85
    }
   ],
   "source": [
    "df_temp = df_ex.copy()\n",
    "new_idx = df_temp.index.map(lambda x: (x[0]+'-'+x[1]+'-'+x[2]))\n",
    "df_temp.index = new_idx\n",
    "df_temp.head() # 单层索引"
   ]
  },
  {
   "source": [
    "同时，也可以反向地展开："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Big         C               D            \n",
       "Small       c       d       c       d    \n",
       "Other     cat dog cat dog cat dog cat dog\n",
       "A a alpha   3   6  -9  -6  -6  -2   0   9\n",
       "    beta   -5  -3   3  -8  -3  -2   5   8\n",
       "  b alpha  -4   4  -1   0   7  -4   6   6\n",
       "    beta   -9   9  -6   8   5  -2  -9  -8\n",
       "B a alpha   0  -9   1  -6   2   9  -7  -9"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead tr th {\n        text-align: left;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Big</th>\n      <th colspan=\"4\" halign=\"left\">C</th>\n      <th colspan=\"4\" halign=\"left\">D</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Small</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n      <th colspan=\"2\" halign=\"left\">c</th>\n      <th colspan=\"2\" halign=\"left\">d</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th></th>\n      <th>Other</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n      <th>cat</th>\n      <th>dog</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"4\" valign=\"top\">A</th>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>alpha</th>\n      <td>3</td>\n      <td>6</td>\n      <td>-9</td>\n      <td>-6</td>\n      <td>-6</td>\n      <td>-2</td>\n      <td>0</td>\n      <td>9</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-5</td>\n      <td>-3</td>\n      <td>3</td>\n      <td>-8</td>\n      <td>-3</td>\n      <td>-2</td>\n      <td>5</td>\n      <td>8</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">b</th>\n      <th>alpha</th>\n      <td>-4</td>\n      <td>4</td>\n      <td>-1</td>\n      <td>0</td>\n      <td>7</td>\n      <td>-4</td>\n      <td>6</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>beta</th>\n      <td>-9</td>\n      <td>9</td>\n      <td>-6</td>\n      <td>8</td>\n      <td>5</td>\n      <td>-2</td>\n      <td>-9</td>\n      <td>-8</td>\n    </tr>\n    <tr>\n      <th>B</th>\n      <th>a</th>\n      <th>alpha</th>\n      <td>0</td>\n      <td>-9</td>\n      <td>1</td>\n      <td>-6</td>\n      <td>2</td>\n      <td>9</td>\n      <td>-7</td>\n      <td>-9</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 86
    }
   ],
   "source": [
    "new_idx = df_temp.index.map(lambda x:tuple(x.split('-')))\n",
    "df_temp.index = new_idx\n",
    "df_temp.head() # 三层索引"
   ]
  },
  {
   "source": [
    "### 3. 索引的设置与重置\n",
    "为了说明本节的函数，下面构造一个新表："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   A  B  C\n",
       "0  a  P  1\n",
       "1  a  Q  2\n",
       "2  c  R  3\n",
       "3  d  T  4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>A</th>\n      <th>B</th>\n      <th>C</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>a</td>\n      <td>P</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>a</td>\n      <td>Q</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>c</td>\n      <td>R</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>d</td>\n      <td>T</td>\n      <td>4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 87
    }
   ],
   "source": [
    "df_new = pd.DataFrame({'A':list('aacd'), 'B':list('PQRT'), 'C':[1,2,3,4]})\n",
    "df_new"
   ]
  },
  {
   "source": [
    "索引的设置可以使用`set_index`完成，这里的主要参数是`append`，表示是否来保留原来的索引，直接把新设定的添加到原索引的内层："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   B  C\n",
       "A      \n",
       "a  P  1\n",
       "a  Q  2\n",
       "c  R  3\n",
       "d  T  4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>B</th>\n      <th>C</th>\n    </tr>\n    <tr>\n      <th>A</th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>a</th>\n      <td>P</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>a</th>\n      <td>Q</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <td>R</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>d</th>\n      <td>T</td>\n      <td>4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 88
    }
   ],
   "source": [
    "df_new.set_index('A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "     B  C\n",
       "  A      \n",
       "0 a  P  1\n",
       "1 a  Q  2\n",
       "2 c  R  3\n",
       "3 d  T  4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>B</th>\n      <th>C</th>\n    </tr>\n    <tr>\n      <th></th>\n      <th>A</th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <th>a</th>\n      <td>P</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <th>a</th>\n      <td>Q</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <th>c</th>\n      <td>R</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <th>d</th>\n      <td>T</td>\n      <td>4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 89
    }
   ],
   "source": [
    "df_new.set_index('A', append=True)"
   ]
  },
  {
   "source": [
    "可以同时指定多个列作为索引："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "     C\n",
       "A B   \n",
       "a P  1\n",
       "  Q  2\n",
       "c R  3\n",
       "d T  4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>C</th>\n    </tr>\n    <tr>\n      <th>A</th>\n      <th>B</th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>P</th>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>Q</th>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <th>R</th>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>d</th>\n      <th>T</th>\n      <td>4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 90
    }
   ],
   "source": [
    "df_new.set_index(['A', 'B'])"
   ]
  },
  {
   "source": [
    "如果想要添加索引的列没有出现在其中，那么可以直接在参数中传入相应的`Series`："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "     B  C\n",
       "A D      \n",
       "a W  P  1\n",
       "  X  Q  2\n",
       "c Y  R  3\n",
       "d Z  T  4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>B</th>\n      <th>C</th>\n    </tr>\n    <tr>\n      <th>A</th>\n      <th>D</th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">a</th>\n      <th>W</th>\n      <td>P</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>X</th>\n      <td>Q</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <th>Y</th>\n      <td>R</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>d</th>\n      <th>Z</th>\n      <td>T</td>\n      <td>4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 91
    }
   ],
   "source": [
    "my_index = pd.Series(list('WXYZ'), name='D')\n",
    "df_new = df_new.set_index(['A', my_index])\n",
    "df_new"
   ]
  },
  {
   "source": [
    "`reset_index`是`set_index`的逆函数，其主要参数是`drop`，表示是否要把去掉的索引层丢弃，而不是添加到列中："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   D  B  C\n",
       "A         \n",
       "a  W  P  1\n",
       "a  X  Q  2\n",
       "c  Y  R  3\n",
       "d  Z  T  4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>D</th>\n      <th>B</th>\n      <th>C</th>\n    </tr>\n    <tr>\n      <th>A</th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>a</th>\n      <td>W</td>\n      <td>P</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>a</th>\n      <td>X</td>\n      <td>Q</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <td>Y</td>\n      <td>R</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>d</th>\n      <td>Z</td>\n      <td>T</td>\n      <td>4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 92
    }
   ],
   "source": [
    "df_new.reset_index(['D'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   B  C\n",
       "A      \n",
       "a  P  1\n",
       "a  Q  2\n",
       "c  R  3\n",
       "d  T  4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>B</th>\n      <th>C</th>\n    </tr>\n    <tr>\n      <th>A</th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>a</th>\n      <td>P</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>a</th>\n      <td>Q</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>c</th>\n      <td>R</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>d</th>\n      <td>T</td>\n      <td>4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 93
    }
   ],
   "source": [
    "df_new.reset_index(['D'], drop=True)"
   ]
  },
  {
   "source": [
    "如果重置了所有的索引，那么`pandas`会直接重新生成一个默认索引："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   A  D  B  C\n",
       "0  a  W  P  1\n",
       "1  a  X  Q  2\n",
       "2  c  Y  R  3\n",
       "3  d  Z  T  4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>A</th>\n      <th>D</th>\n      <th>B</th>\n      <th>C</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>a</td>\n      <td>W</td>\n      <td>P</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>a</td>\n      <td>X</td>\n      <td>Q</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>c</td>\n      <td>Y</td>\n      <td>R</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>d</td>\n      <td>Z</td>\n      <td>T</td>\n      <td>4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 94
    }
   ],
   "source": [
    "df_new.reset_index()"
   ]
  },
  {
   "source": [
    "### 4. 索引的变形\n",
    "在某些场合下，需要对索引做一些扩充或者剔除，更具体地要求是给定一个新的索引，把原表中相应的索引对应元素填充到新索引构成的表中。例如，下面的表中给出了员工信息，需要重新制作一张新的表，要求增加一名员工的同时去掉身高列并增加性别列："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "      Weight  Height\n",
       "1001      60     176\n",
       "1003      70     180\n",
       "1002      80     179"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>Weight</th>\n      <th>Height</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>1001</th>\n      <td>60</td>\n      <td>176</td>\n    </tr>\n    <tr>\n      <th>1003</th>\n      <td>70</td>\n      <td>180</td>\n    </tr>\n    <tr>\n      <th>1002</th>\n      <td>80</td>\n      <td>179</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 95
    }
   ],
   "source": [
    "df_reindex = pd.DataFrame({\"Weight\":[60,70,80], \"Height\":[176,180,179]}, index=['1001','1003','1002'])\n",
    "df_reindex"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "      Weight  Gender\n",
       "1001    60.0     NaN\n",
       "1002    80.0     NaN\n",
       "1003    70.0     NaN\n",
       "1004     NaN     NaN"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>Weight</th>\n      <th>Gender</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>1001</th>\n      <td>60.0</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>1002</th>\n      <td>80.0</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>1003</th>\n      <td>70.0</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>1004</th>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 96
    }
   ],
   "source": [
    "df_reindex.reindex(index=['1001','1002','1003','1004'], columns=['Weight','Gender'])"
   ]
  },
  {
   "source": [
    "这种需求常出现在时间序列索引的时间点填充以及`ID`编号的扩充。另外，需要注意的是原来表中的数据和新表中会根据索引自动对齐，例如原先的1002号位置在1003号之后，而新表中相反，那么`reindex`中会根据元素对齐，与位置无关。\n",
    "\n",
    "还有一个与`reindex`功能类似的函数是`reindex_like`，其功能是仿照传入的表索引来进行被调用表索引的变形。例如，现在已经存在一张表具备了目标索引的条件，那么上述功能可采用下述代码得到："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "      Weight  Gender\n",
       "1001    60.0     NaN\n",
       "1002    80.0     NaN\n",
       "1003    70.0     NaN\n",
       "1004     NaN     NaN"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>Weight</th>\n      <th>Gender</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>1001</th>\n      <td>60.0</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>1002</th>\n      <td>80.0</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>1003</th>\n      <td>70.0</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>1004</th>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 97
    }
   ],
   "source": [
    "df_existed = pd.DataFrame(index=['1001','1002','1003','1004'], columns=['Weight','Gender'])\n",
    "df_reindex.reindex_like(df_existed)"
   ]
  },
  {
   "source": [
    "## 四、索引运算\n",
    "### 1. 集合的运算法则\n",
    "\n",
    "经常会有一种利用集合运算来取出符合条件行的需求，例如有两张表`A`和`B`，它们的索引都是员工编号，现在需要筛选出两表索引交集的所有员工信息，此时通过`Index`上的运算操作就很容易实现。\n",
    "\n",
    "不过在此之前，不妨先复习一下常见的四种集合运算："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "$$\\rm S_A.intersection(S_B) = \\rm S_A \\cap S_B \\Leftrightarrow \\rm \\{x|x\\in S_A\\, and\\, x\\in S_B\\}$$\n",
    "$$\\rm S_A.union(S_B) = \\rm S_A \\cup S_B \\Leftrightarrow \\rm \\{x|x\\in S_A\\, or\\, x\\in S_B\\}$$\n",
    "$$\\rm S_A.difference(S_B) = \\rm S_A - S_B \\Leftrightarrow \\rm \\{x|x\\in S_A\\, and\\, x\\notin S_B\\}$$\n",
    "$$\\rm S_A.symmetric\\_difference(S_B) = \\rm S_A\\triangle S_B\\Leftrightarrow \\rm \\{x|x\\in S_A\\cup S_B - S_A\\cap S_B\\}$$"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "### 2. 一般的索引运算"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "由于集合的元素是互异的，但是索引中可能有相同的元素，先用`unique`去重后再进行运算。下面构造两张最为简单的示例表进行演示："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Index(['b'], dtype='object')"
      ]
     },
     "metadata": {},
     "execution_count": 98
    }
   ],
   "source": [
    "df_set_1 = pd.DataFrame([[0,1],[1,2],[3,4]], index = pd.Index(['a','b','a'],name='id1'))\n",
    "df_set_2 = pd.DataFrame([[4,5],[2,6],[7,1]], index = pd.Index(['b','b','c'],name='id2'))\n",
    "id1, id2 = df_set_1.index.unique(), df_set_2.index.unique()\n",
    "id1.intersection(id2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Index(['a', 'b', 'c'], dtype='object')"
      ]
     },
     "metadata": {},
     "execution_count": 99
    }
   ],
   "source": [
    "id1.union(id2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Index(['a'], dtype='object')"
      ]
     },
     "metadata": {},
     "execution_count": 100
    }
   ],
   "source": [
    "id1.difference(id2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "Index(['a', 'c'], dtype='object')"
      ]
     },
     "metadata": {},
     "execution_count": 101
    }
   ],
   "source": [
    "id1.symmetric_difference(id2)"
   ]
  },
  {
   "source": [
    "若两张表需要做集合运算的列并没有被设置索引，一种办法是先转成索引，运算后再恢复，另一种方法是利用`isin`函数，例如在重置索引的第一张表中选出id列交集的所在行："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "  id1  0  1\n",
       "0   a  0  1\n",
       "1   b  1  2\n",
       "2   a  3  4"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>id1</th>\n      <th>0</th>\n      <th>1</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>a</td>\n      <td>0</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>b</td>\n      <td>1</td>\n      <td>2</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>a</td>\n      <td>3</td>\n      <td>4</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 102
    }
   ],
   "source": [
    "df_set_in_col_1 = df_set_1.reset_index()\n",
    "df_set_in_col_2 = df_set_2.reset_index()\n",
    "df_set_in_col_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "  id2  0  1\n",
       "0   b  4  5\n",
       "1   b  2  6\n",
       "2   c  7  1"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>id2</th>\n      <th>0</th>\n      <th>1</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>b</td>\n      <td>4</td>\n      <td>5</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>b</td>\n      <td>2</td>\n      <td>6</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>c</td>\n      <td>7</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 103
    }
   ],
   "source": [
    "df_set_in_col_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "  id1  0  1\n",
       "1   b  1  2"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>id1</th>\n      <th>0</th>\n      <th>1</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>1</th>\n      <td>b</td>\n      <td>1</td>\n      <td>2</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 104
    }
   ],
   "source": [
    "df_set_in_col_1[df_set_in_col_1.id1.isin(df_set_in_col_2.id2)]"
   ]
  },
  {
   "source": [
    "## 五、练习\n",
    "### Ex1：公司员工数据集\n",
    "现有一份公司员工数据集："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "   EmployeeID birthdate_key  age  city_name department      job_title gender\n",
       "0        1318      1/3/1954   61  Vancouver  Executive            CEO      M\n",
       "1        1319      1/3/1957   58  Vancouver  Executive      VP Stores      F\n",
       "2        1320      1/2/1955   60  Vancouver  Executive  Legal Counsel      F"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>EmployeeID</th>\n      <th>birthdate_key</th>\n      <th>age</th>\n      <th>city_name</th>\n      <th>department</th>\n      <th>job_title</th>\n      <th>gender</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>1318</td>\n      <td>1/3/1954</td>\n      <td>61</td>\n      <td>Vancouver</td>\n      <td>Executive</td>\n      <td>CEO</td>\n      <td>M</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>1319</td>\n      <td>1/3/1957</td>\n      <td>58</td>\n      <td>Vancouver</td>\n      <td>Executive</td>\n      <td>VP Stores</td>\n      <td>F</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>1320</td>\n      <td>1/2/1955</td>\n      <td>60</td>\n      <td>Vancouver</td>\n      <td>Executive</td>\n      <td>Legal Counsel</td>\n      <td>F</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 105
    }
   ],
   "source": [
    "df = pd.read_csv('../data/company.csv')\n",
    "df.head(3)"
   ]
  },
  {
   "source": [
    "1. 分别只使用`query`和`loc`选出年龄不超过四十岁且工作部门为`Dairy`或`Bakery`的男性。\n",
    "2. 选出员工`ID`号 为奇数所在行的第1、第3和倒数第2列。\n",
    "3. 按照以下步骤进行索引操作：\n",
    "\n",
    "* 把后三列设为索引后交换内外两层\n",
    "* 恢复中间层索引\n",
    "* 修改外层索引名为`Gender`\n",
    "* 用下划线合并两层行索引\n",
    "* 把行索引拆分为原状态\n",
    "* 修改索引名为原表名称\n",
    "* 恢复默认索引并将列保持为原表的相对位置"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "### Ex2：巧克力数据集\n",
    "现有一份关于巧克力评价的数据集："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "    Company  Review\\nDate Cocoa\\nPercent Company\\nLocation  Rating\n",
       "0  A. Morin          2016            63%            France    3.75\n",
       "1  A. Morin          2015            70%            France    2.75\n",
       "2  A. Morin          2015            70%            France    3.00"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>Company</th>\n      <th>Review\\nDate</th>\n      <th>Cocoa\\nPercent</th>\n      <th>Company\\nLocation</th>\n      <th>Rating</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>A. Morin</td>\n      <td>2016</td>\n      <td>63%</td>\n      <td>France</td>\n      <td>3.75</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>A. Morin</td>\n      <td>2015</td>\n      <td>70%</td>\n      <td>France</td>\n      <td>2.75</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>A. Morin</td>\n      <td>2015</td>\n      <td>70%</td>\n      <td>France</td>\n      <td>3.00</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "metadata": {},
     "execution_count": 106
    }
   ],
   "source": [
    "df = pd.read_csv('../data/chocolate.csv')\n",
    "df.head(3)"
   ]
  },
  {
   "source": [
    "1. 把列索引名中的`\\n`替换为空格。\n",
    "2. 巧克力`Rating`评分为1至5，每0.25分一档，请选出2.75分及以下且可可含量`Cocoa Percent`高于中位数的样本。\n",
    "3. 将`Review Date`和`Company Location`设为索引后，选出`Review Date`在2012年之后且`Company Location`不属于`France, Canada, Amsterdam, Belgium`的样本。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  }
 ]
}